想象一下,我有一个csv,每个值都是一个整数。所以第一个值是INTEGER 100
。
我希望fscanf()读取这一行,并告诉我它只是一个整数,或者不是。因此,它将通过100
但在100t
上失败。我一直想要的工作是“%d”,其中逗号是我的CSV的分隔符。所以整个功能是
fscanf(fp, "%d,", &count)
不幸的是,这不能在'100t'失败,'在'100'上工作并且在't'上工作。所以它只是没有区分100
和100t
(所有这些数字后面都有逗号,当然
答案 0 :(得分:7)
改为使用strtol
。
答案 1 :(得分:5)
你没有。
问题是fscanf()
不是很有用。处理它的最好方法是读取整行(或行的重要部分),然后分析字符串。这是一个例子:
int value;
char *extra;
char buffer[100];
// read in some data from the buffer
fgets(buffer, sizeof buffer, stdin);
// parse out a digit, if we can
i = strtol(buffer, &extra, 0);
此时,您可以检查extra
以查看是否有任何额外字符,这意味着该行不是纯数字,或者extra
指向{{1}的开头},意思是没有要解析的数字。
答案 2 :(得分:5)
fscanf实际上比其他一些答案所暗示的更有用 - 但是大多数人并不了解它,也不知道如何运用它的全部功能。
有用的要点:首先,使用fscanf的返回值 - 它告诉你转换了多少项。其次,“扫描设置”转换非常有用。请考虑以下内容(我使用sscanf
来避免需要外部文件,但fscanf
仅在其读取的源中有所不同:
#include <stdio.h>
int main() {
int i;
char *test[] = {
"100,", // should succeed.
"100t,", // should fail.
"t" // should also fail.
};
for (i=0; i<3; i++) {
int count;
char ch[2];
if (2 == sscanf(test[i], "%d%[,]", &count, &ch))
fprintf(stderr, "Conversion of \"%s\" succeeded.\n", test[i]);
else
fprintf(stderr, "Conversion of \"%s\" failed.\n", test[i]);
}
return 0;
}
答案 3 :(得分:1)
怎么样?
fscanf(fp, "%d%c", &count, &aChar)
如果aChar!=','&amp;&amp; !='\ n'然后你没有一个整数
答案 4 :(得分:0)
输入上的scanf函数不是100%控制可能很容易获得无错误,最好使用fgets()读取行,然后使用strtok()将行拆分为令牌,然后可以转换。
在像“100t”之类的一个标记上使用atoi然后将产生0,而“100”将产生100
答案 5 :(得分:0)
scanf()
系列函数不太适合检测此类错误。这不是不可能的(参见Jerry Coffin的答案,其中有效但IMO难以概括),但IMO并不那么强大。更好的选择是使用fgets()
将输入作为文本读取,使用strtok()
或类似方式进行标记,然后使用strtol()
或strtod()
将标记转换为数值:
char buffer[LINE_SIZE];
while (fgets(buffer, sizeof buffer, inFile))
{
char *token;
char *newline = strchr(buffer, '\n');
if (newline)
*newline = 0;
token = strtok(buffer, ",");
while (token)
{
char *chk;
int value = (int) strtol(token, &chk, 10);
if (!isspace(*chk) && *chk != 0)
{
printf("%s is not a valid integer\n", token);
}
else
{
printf("successfully read integer value %d\n", val);
}
token = strtok(NULL, ",");
}
}
if (feof(inFile))
{
printf("Hit end-of-file\n");
}
else
{
printf("Error during read\n");
}