使用fscanf读入项目

时间:2013-01-24 08:11:01

标签: c

有一个文件a.txt如下所示:

1 abc
2 
3 jkl

我想将此文件的每一行都读为int和一个字符串,如下所示:

fp = fopen("a.txt", "r");
while (1) {
    int num;
    char str[10];
    int ret =fscanf(fp, "%d%s", &num, str);
    if (EOF == ret)
        break;
    else if (2 != ret)
        continue;
    // do something with num and str
}

但是有一个问题,如果a.txt中的一行只包含一个数字,没有字符串(就像第2行一样),那么上面的代码就会卡在那一行。

那么有什么方法可以跳到下一行吗?

3 个答案:

答案 0 :(得分:2)

分两步完成:

  1. 使用fgets()阅读整行。这假设你可以对你想要支持的行数设置一个简单的静态限制,但这种情况经常发生。
  2. 使用sscanf()检查并解析该行。
  3. 这可以解决您遇到的问题,对于像这样的问题通常是更好的方法。

    更新:尝试回复您的评论。我看到它的方式,最简单的方法是始终读取整行(如上所述),然后解析您认为它包含的两个字段:数字和字符串。

    如果您使用sscanf()执行此操作,则可以使用返回值来确定其运行方式,就像您在代码中尝试使用fscanf()一样:

    const int num_fields = sscanf(line, "%d %s", &num, str);
    if( num_fields == 1 )
      ; /* we got only the number */
    else if( num_fields == 2 )
      ; /* we got both the number and the string */
    else
      ; /* failed to get either */
    

    不确定何时不“需要”字符串;它要么存在,要么不存在。

答案 1 :(得分:1)

如果字符串的第一个字符是\r or\n,则这将是一个空字符串。您可以使用比较。如果单词中包含空格(或空行),则fscanf()不合适。在这种情况下,最好使用fgets()

答案 2 :(得分:1)

如何解决"使用fscanf":

int之后,查找空格(不要保存),然后查找不是char的{​​{1}}。

'\n'
如果将某些内容扫描到int num; char str[10]; #define ScanInt "%d" #define ScanSpacesDontSave "%*[ ]" #define ScanUntilEOL "%9[^\n]" int ret = fscanf(fp, ScanInt ScanSpacesDontSave ScanUntilEOL, &num, str); if (EOF == ret) break; else if (1 == ret) HandleNum(num); else if (2 == ret) HandleNumStr(num, str); else HadleMissingNum();

ret将为2,否则str通常为1.上述技巧不是扫描在ret之后'\n'。因此代码不能在int之后使用"%s"" ",它们都消耗所有(领先)空白区域。 下一次 "%d"调用将通过fscanf()消耗'\n'作为领先空白消费的一部分。

次要注意:使用"%d"读取行然后解析缓冲区通常是一种更好的方法,但编码目标可能会排除这种情况。