scanf 改写从对话框格式化输入

Yofoo 2008-07-22 01:06:55
scanf 本来是控制台的标准输入(键盘), 现在需要改写用对话框输入来替换,
从对话框输入字符串的函数已经写好, 关键是格式化输入的转换部分如何写?


int NDlg::InputScanf(const CHAR *format, ...)
{
CHAR szBuf[1024];
szBuf[0] = 0;
GetInput(NULL, szBuf, sizeof(szBuf), "InputScanf", 300); //该函数从对话框输入字符串 已经写好

...//格式化输入的转换 如何写?
}




printf已经改写成写入文件, 改写成功, 有函数 _vsnprintf 可用, 但是scanf 没有
后来查看scanf的源代码发现用_input 函数, 但是该函数只有在Debug才有, Release没有, 所以也不行




//printf 改写写入文件 NLog::LogPrintf
int NLog::LogPrintf(CONST CHAR * lpszFormat, ...)
{
CHAR * buf = NULL;
int nRetVal = -1, nSize = 4096;
va_list args;

if(lpszFormat == NULL)
return Logs(NULL);

va_start(args, lpszFormat);

for(; nRetVal<0 ; nSize*=2)
{
if(buf)
free(buf);

buf = (CHAR *)malloc( (nSize+2)*sizeof(CHAR) );
nRetVal = _vsnprintf(buf, nSize, lpszFormat, args);
}

va_end(args);

nRetVal = Logs(buf);

if(buf)
free(buf);
return nRetVal;
}

int NLog::Logs(CHAR *pString, CHAR *pLogFile)
{
HANDLE hFile;
int nLen, nError;
BOOL bRetVal;
DWORD dwRetVal, dwLenWrite;

if(pLogFile == NULL)
{
pLogFile = s_ThisLogFile;
}

if(pString == NULL)
{
hFile = CreateFileA(pLogFile, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL, CREATE_ALWAYS , 0, NULL);
CloseHandle(hFile);
return 0;
}

hFile = CreateFileA(pLogFile, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL, OPEN_ALWAYS, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
return -1;
}

nLen = (int)strlen(pString);
dwRetVal = SetFilePointer(hFile, 0, 0, FILE_END);
if(dwRetVal == 0xFFFFFFFF)
{
nError = ::GetLastError();
if(nError != NO_ERROR)
{
CloseHandle(hFile);
::SetLastError(nError);
return -1;
}
}

bRetVal = WriteFile(hFile, pString, nLen, &dwLenWrite, NULL);
if(bRetVal == FALSE)
{
nError = ::GetLastError();
CloseHandle(hFile);
::SetLastError(nError);
return -1;
}
CloseHandle(hFile);
return dwLenWrite;
}
...全文
250 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
hurryboylqs 2008-07-23
  • 打赏
  • 举报
回复
学习
wangjs720 2008-07-23
  • 打赏
  • 举报
回复
sscanf
cnzdgs 2008-07-23
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 zzz3265 的回复:]
感谢 Amuro1987218 , cnzdgs

但是不怎么理想,
Amuro1987218 需要-1 作结束标记
cnzdgs 用foemat中的 '%' 来判断参数个数, 有时并不准确, 如 "%%", "%*"
[/Quote]
这个问题我考虑过了,scanf通常是不需要使用%%的,即使这样使用,也只是给sscanf多传递了参数而已,C函数调用规则会自动忽略多传递的参数,不会有任何影响。(当然,如果%相当多时可能会导致栈越界,但可能性太低了,如果要考虑这种情况,可以在统计%时做一个最大个数的限制。)
hua_yang 2008-07-23
  • 打赏
  • 举报
回复
mark, 学习
schlafenhamster 2008-07-23
  • 打赏
  • 举报
回复
全是assemble, 晕
Eleven 2008-07-23
  • 打赏
  • 举报
回复
学习。。。
Yofoo 2008-07-23
  • 打赏
  • 举报
回复
感谢 Amuro1987218 , cnzdgs

但是不怎么理想,
Amuro1987218 需要-1 作结束标记
cnzdgs 用foemat中的 '%' 来判断参数个数, 有时并不准确, 如 "%%", "%*"


我自己也想了个方法, 不过静态变量用的多


__declspec(naked) int NDlg::InputScanf(const CHAR *format, ...)
{
static CHAR szBuf[1024];
static BYTE ** pReqsAddr;
static BYTE * pOldValue;
static BYTE * OldEsp;
static BYTE * SetEsp;

static BYTE * OldEbx;
static BYTE * OldEcx;
static BYTE * OldEdx;
static BYTE * OldEsi;
static BYTE * OldEdi;
static BYTE * OldEbp;

static int UintSize = sizeof(int);

__asm mov OldEbx, ebx;
__asm mov OldEcx, ecx;
__asm mov OldEdx, edx;
__asm mov OldEsi, esi;
__asm mov OldEdi, edi;
__asm mov OldEbp, ebp;

__asm sub esp, UintSize
__asm mov ebp, esp
__asm sub esp, __LOCAL_SIZE

pReqsAddr = (BYTE **)(&format - 1);
SetEsp = (BYTE *)(pReqsAddr);
pOldValue = *pReqsAddr;

szBuf[0] = 0;
GetInput(NULL, szBuf, sizeof(szBuf), "InputScanf", 300);

*pReqsAddr = (BYTE *)szBuf;

__asm mov OldEsp, esp;
__asm mov esp, SetEsp;
__asm call sscanf
__asm mov esp, OldEsp;

*pReqsAddr = pOldValue;

__asm mov ebx, OldEbx;
__asm mov ecx, OldEcx;
__asm mov edx, OldEdx;
__asm mov esi, OldEsi;
__asm mov edi, OldEdi;


__asm mov esp, ebp
__asm mov ebp, OldEbp;
__asm add esp, UintSize
__asm ret
}
Torch009 2008-07-23
  • 打赏
  • 举报
回复
学习
CLIZ 2008-07-22
  • 打赏
  • 举报
回复
用sscanf可以从一个串中提取需要格式的数据。比如:
串是s="123 abc"
int n; char string[10];
sscanf(s, "%d %s", &n, string);
可以得到n=123,string="abc"
shanying_0 2008-07-22
  • 打赏
  • 举报
回复
学习中.水平还不够~~~~
Amuro1987218 2008-07-22
  • 打赏
  • 举报
回复
学习一下

mov ecx, len
sub esp, ecx
lea esi, format
mov edi, esp
rep movsb

思路很巧妙
cnzdgs 2008-07-22
  • 打赏
  • 举报
回复
最后漏掉了一行:return result;
cnzdgs 2008-07-22
  • 打赏
  • 举报
回复
int NDlg::InputScanf(const CHAR *format, ...)
{
CHAR szBuf[1024];
szBuf[0] = 0;
GetInput(NULL, szBuf, sizeof(szBuf), "InputScanf", 300);

int result;
LPCSTR buffer = szBuf;
LPCSTR p = format;
int count = 1;
while (*p != 0)
{
if (*p++ == '%') count++;
}
int len = count << 2;
__asm {
pushad
mov ecx, len
sub esp, ecx
lea esi, format
mov edi, esp
rep movsb
push buffer
call sscanf
mov result, eax
pop eax
add esp, len
popad
}
}
scq2099yt 2008-07-22
  • 打赏
  • 举报
回复
str.Format
Amuro1987218 2008-07-22
  • 打赏
  • 举报
回复
LZ我写了一个..比较粗糙


	void InputScanf(const char* format, ...) 
{

va_list arg_ptr;
va_start(arg_ptr, format);
std::stack<int> args;
int arg =0;//每个参数
int number=0;//参数个数
char szTest[] = "12 34";//test Input Text
char* Point = &szTest[0];//point to c-style string

/*
**本函数规定以-1为结束标志
*/
while(arg != -1)
{
++number;
arg = va_arg(arg_ptr,int);
args.push(arg);
}
va_end(arg_ptr);


for(int i=0;i<number;++i)
{
arg= args.top();
args.pop();

__asm push arg;//__cdecl右到左压栈
}

__asm push format;
__asm push Point;
__asm call sscanf;//.
}


使用的例子
int a,b;

InputScanf("%d %d",&a,&b,-1);

CString str;
str.Format("%d %d",a,b);
AfxMessageBox(str);

zhoujianhei 2008-07-22
  • 打赏
  • 举报
回复
先写入文件,再
fscanf

Yofoo 2008-07-22
  • 打赏
  • 举报
回复
CHAR szBuf[1024];
int nTemp;

NDlg::InputScanf("%d %s", &nTemp, szBuf);

对话框输入字符串 "25 asdfgh" 后
nTemp 变成 25
szBuf 变成 "asdfgh"

NDlg::InputScanf 应该怎么写, 不要还说看不懂!

FORTUNATE99 2008-07-22
  • 打赏
  • 举报
回复
scanf 本来是控制台的标准输入(键盘), 现在需要改写用对话框输入来替换,
从对话框输入字符串的函数已经写好, 关键是格式化输入的转换部分如何写?

//MFC有MFC的函数,既然使用的MFC,为什么还用纯C的scanf,printf?
//用GetDlgItemText() 和 CString::Format()
cnzdgs 2008-07-22
  • 打赏
  • 举报
回复
不是很清楚你的目的,你是要处理本进程还是其它进程?要输入的数据是对应一个字符串吗?是否可以把问题理解为把scanf用等待窗口事件和sscanf替代?
Amuro1987218 2008-07-22
  • 打赏
  • 举报
回复
没太看懂
加载更多回复(2)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧