[英]C - how to get fscanf() to determine whether what it read is only digits, and no characters
假设我有一个csv,每个值都是一个整数。 所以第一个值是INTEGER 100
。
我想让fscanf()读取这一行,并告诉我它仅是整数,还是不是。 因此,它将超过100
但在100t
失败。 我一直在努力工作的是“%d”,其中逗号是我的CSV的分隔符。 所以整个功能是
fscanf(fp, "%d,", &count)
不幸的是,这不能在'100t'上失败,在'100'上有效,在't'上有效。 因此,它只是不能区分100
100t
和100
100t
(当然,所有这些数字后面都带有逗号
请改用strtol
。
你不知道
问题是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
点的开始buffer
,这意味着没有号码解析。
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;
}
关于什么
fscanf(fp, "%d%c", &count, &aChar)
如果aChar!=','&&!='\\ n'那么您就没有整数
不受100%控制的输入上的scanf-functions可能很难获得无错误,最好使用fgets()读取行,然后使用strtok()将行拆分为令牌,然后可以将其转换。
在一个像“ 100t”这样的令牌上使用atoi将产生0,而“ 100”将产生100
scanf()
系列函数不太善于检测这种错误。 这不是不可能的(请参阅杰里·科芬的答案,该方法虽然有效,但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");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.