C - 如何让fscanf()确定它读取的内容是否只是数字,而不是字符

时间:2010-04-11 03:33:03

标签: c scanf

想象一下,我有一个csv,每个值都是一个整数。所以第一个值是INTEGER 100

我希望fscanf()读取这一行,并告诉我它只是一个整数,或者不是。因此,它将通过100但在100t上失败。我一直想要的工作是“%d”,其中逗号是我的CSV的分隔符。所以整个功能是

fscanf(fp, "%d,", &count)

不幸的是,这不能在'100t'失败,'在'100'上工作并且在't'上工作。所以它只是没有区分100100t(所有这些数字后面都有逗号,当然

6 个答案:

答案 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");
}