繁体   English   中英

使用fscanf读取项目

[英]using fscanf to read in items

有一个文件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中的一行仅包含一个num,没有任何字符串(就像第2行一样),那么上面的代码将停留在该行中。

有什么办法跳到下一行吗?

分两个步骤进行:

  1. 使用fgets()阅读整行。 假设您可以对要支持的行数设置简单的静态限制,但是通常是这种情况。
  2. 使用sscanf()检查并分析该行。

这可以解决您遇到的问题,通常是解决此类问题的更好方法。

更新 :试图回应您的评论。 以我的方式来看,最简单的方法是始终读取完整的行(如上),然后解析出您认为由其组成的两个字段:数字和字符串。

如果使用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 */

不知道什么时候不需要“字符串”; 它在那儿或不在那儿。

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

如何解决“使用fscanf”:

int ,查找空格(不保存),然后查找不是'\\n' char

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();

如果将某些内容扫描到strret将为2,否则ret通常将为1。上面的技巧是不要在int之后扫描'\\n' 因此,代码不能使用"%s"" " "%d"之后的"%d" ,它们都占用了所有(前导)空白。 下一个 fscanf()调用将通过"%d"消耗'\\n'作为前导空白消耗的一部分。

小注释:使用fgets()读取行然后解析缓冲区通常是一种更好的方法,但是编码目标可能会阻止这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM