Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用fscanf读入项目_C - Fatal编程技术网

使用fscanf读入项目

使用fscanf读入项目,c,C,有一个文件a.txt如下所示: 1 abc 2 3 jkl 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

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

1 abc
2 
3 jkl
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
}
我想将此文件的每一行读取为一个
int
和一个字符串,如下所示:

1 abc
2 
3 jkl
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行一样),那么上面的代码将卡在该行中


有没有办法跳到下一行?

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

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

分两步执行:

  • 使用
    fgets()
    阅读全文。这假设您可以对要支持的行的长度设置一个简单的静态限制,但通常情况下是这样的
  • 使用
    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 */
    
    不确定什么时候你不需要绳子;它要么在那里,要么不在那里。

    分两步进行:

  • 使用
    fgets()
    阅读全文。这假设您可以对要支持的行的长度设置一个简单的静态限制,但通常情况下是这样的
  • 使用
    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 */
    
    不确定什么时候你不需要绳子;它要么存在,要么不存在。

    如何解决“使用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();
    
    如果将某物扫描到
    str
    ,则
    ret
    将为2,否则
    ret
    通常为1。上面的技巧是不要在
    int
    之后扫描
    '\n'
    。因此,代码不能在
    “%d”
    之后使用
    “%s”
    ,这两者都会占用所有(前导)空格。下一个
    fscanf()
    调用将通过
    %d”
    消耗
    '\n'
    作为主要空白消耗的一部分

    次要提示:使用
    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();
    
    如果将某物扫描到
    str
    ,则
    ret
    将为2,否则
    ret
    通常为1。上面的技巧是不要在
    int
    之后扫描
    '\n'
    。因此,代码不能在
    “%d”
    之后使用
    “%s”
    ,这两者都会占用所有(前导)空格。下一个
    fscanf()
    调用将通过
    %d”
    消耗
    '\n'
    作为主要空白消耗的一部分


    次要提示:使用
    fgets()
    读取行,然后解析缓冲区通常是一种更好的方法,但编码目标可能会排除这一点。

    int-ret=fscanf(“%d%s”,&num,str)您是否忘记在这个调用中引用fp?它应该是int-ret=fscanf(fp、%d%s、&num、str)@zdesam,很抱歉,你有什么异常吗?@zdesam,没有异常,但是
    while循环
    卡在了a.txt的第二行,因为该行只包含一个num-no字符串,所以
    fscanf
    不匹配,它不会跳到下一行。可能你可以试试“%d\n%s”int-ret=fscanf(“%d%s”,&num,str)你忘了在这次通话中提及fp吗?它应该是int-ret=fscanf(fp、%d%s、&num、str)@zdesam,很抱歉,你有什么异常吗?@zdesam,没有异常,但是
    while循环
    卡在a.txt的第二行,因为该行只包含一个num no字符串,所以
    fscanf
    不匹配,它不会跳到下一行。也许你可以试试“%d\n%s”,谢谢。如果我不需要num后面的字符串,我的意思是可以使用这个
    fscanf(fp、%u%*c、&num)?嗯,我试图通过一次性使用
    fscanf
    来完成这项工作,但谢谢你,伙计;-)谢谢如果我不需要num后面的字符串,我的意思是可以使用这个
    fscanf(fp、%u%*c、&num)?嗯,我试图通过一次性使用
    fscanf
    来完成这项工作,但谢谢你,伙计;-)