2012-01-12 18 views
5

对不起,我简单的问题,但我试图找到一种优雅的方式,以避免我的程序看一些像“14asdf”输入和接受它,就像14忽略整数是使用的sscanf()旁边的字符

if (sscanf(sInput, "%d", &iAssignmentMarks[0]) != 0) 

有没有一种简单的方法来防止sscanf从整理出来的损坏的字符串?

+0

你的意思是有没有办法让sscanf只能拿起这样的字符串中的数字字符?您可能还想澄清您是否希望“53sd2”返回53或532. – Ian 2012-01-12 21:13:08

+0

对不起,我应该更清楚一点,我希望“14asdf”被识别为无效输入,就像“53sd2”一样。我只想识别独立的整数(至少是空格分隔),而不是非数字字符。 – ARW 2012-01-12 21:23:18

+0

在C++中这很容易。也许应该从这个问题中删除'C++'标签? @AdamWathan,你只需要在C中工作的答案? – 2012-01-13 00:44:04

回答

3

您不能直接停止sscanf()做它设计和指定做的事情。但是,你可以使用的sscanf()一个名不见经传的和很少使用的功能,可以很容易地发现,有一个问题:

int i; 

if (sscanf(sInput, "%d%n", &iAssignmentMarks[0], &i) != 1) 
    ...failed to recognize an integer... 
else if (!isspace(sInput[i]) && sInput[i] != '\0') 
    ...character after integer was not a space character (including newline) or EOS... 

%n上的字符数指令报告消耗到这一点, ,并不算作转换(因此只有一种格式的转换)。自C89以来,%nsscanf()中的标准配置。您可以使用strtol() - 仔细地(使用它检测错误条件非常困难,但它优于不会报告或检测溢出的sscanf())。对于提取单个整数,您也可以使用strtol()。但是,这种技术可以以单一格式多次使用,这通常更方便。

2

你想从字符串中读取整数。用strtol而不是sscanf这样做更容易。 strtol将通过endptr间接返回最后一个成功读入数字的字符后面的地址。如果且只有,该字符串是一个数字,则endptr将指向您的数字字符串的末尾,即*endptr == \0

char *endptr = NULL; 
long n = strtol(sInput, &endptr, 10); 
bool isNumber = endptr!=NULL && *endptr==0 && errno==0; 

(初始的空白将被忽略。详见一个strtol man page

+0

为了解释代码,我在答案中添加了一些文本。我希望你不介意@ Serge-appTranslator。随意编辑或删除它。 – 2012-01-13 00:50:21

+1

什么?文本?为什么不在评论代码的时候呢! :-)谢谢Aaron – 2012-01-13 06:51:20

0

scanf不是那么聪明。你必须读取输入文字和利用strtol将其转换。其中一个参数strtolchar *将指向未转换的第一个字符;如果该字符不是空格或0,然后输入字符串不是有效的整数:

char input[SIZE]; // where SIZE is large enough for the expected values plus 
        // a sign, newline character, and 0 terminator 
... 
if (fgets(input, sizeof input, stdin)) 
{ 
    char *chk; 
    long val = strtol(input, &chk, 10); 
    if (*chk == NULL || !isspace(*chk) && *chk != 0) 
    { 
    // input wasn't an integer string 
    } 
} 
+0

问题是关于'sscanf',而不是'scanf',因此数据已经在一个字符串中。参见@ Serge的回答。 – 2012-01-13 00:51:28

+0

这是不正确的:你可以使用'[fs] scanf()'来做这件事:你只需要尝试读取数字后面的内容并检查读取的元素的数量。 – 2012-01-13 01:05:03

2

这很简单。没有花哨的C++需要!只要这样做:

char unusedChar; 
if (sscanf(sInput, "%d%c", &iAssignmentMarks[0], &unusedChar) == 1)