C语言 如何使用 fscanf 扫描 C 中的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19323113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:41:47  来源:igfitidea点击:

How do I scan a file in C using fscanf

cscanf

提问by user2823747

I am using the code

我正在使用代码

while(fscanf(input, "%49[^@ ]@%49s -> %49[^@ ]@%49s", sender, trash, receiver, trash) != EOF){
   printf("%s " "%s\n", sender, reciever);
}

to try to read and print every line from a file however when I run this code it gets stuck in an endless loop printing the first line of the file over and over again. How can I move the scanner down to the next line after it has executed this code. Thank you in advance for any help.

尝试读取和打印文件中的每一行,但是当我运行此代码时,它会陷入无限循环,一遍又一遍地打印文件的第一行。执行此代码后,如何将扫描仪向下移动到下一行。预先感谢您的任何帮助。

回答by Fernando Carvalho

#include < stdio.h >

FILE *fr;

main()
{
    int n;
    char line[80];

    fr = fopen ("test.txt", "r");  /* open the file for reading */

    while(fgets(line, 80, fr) != NULL)
    {
    /* get a line, up to 80 chars from fr.  done if NULL */
    sscanf  ( line );
    }
    fclose(fr);  /* close the file prior to exiting the routine */
}

The basic way to do what you want...

做你想做的事的基本方法......

回答by hiddenguy

  do {
        fscanf(input, "%49[^@ ]@%49s -> %49[^@ ]@%49s", sender, trash, receiver, trash);
        printf("%s " "%s\n", sender, reciever);
     } while(!feof(input));

回答by el.pescado

You should check return value from fscanf. This function returns number of succesful conversions, which may be less than number of conversions specified in format string.

您应该检查从fscanf. 此函数返回成功转换的次数,可能小于格式字符串中指定的转换次数。

In your case, it may mean that no conversions may have been performed in second call to fscanf, becaude of malformed data in file etc. As no data was read, file handle has not advanced, so end-of-file hasn't been reached, which in turn explains why loop does not terminate. As no data was read, previous values are printed in each loop iteration.

在您的情况下,这可能意味着在第二次调用中可能没有执行转换fscanf,因为文件中的数据格式错误等。由于没有读取数据,文件句柄没有前进,所以没有到达文件末尾,这反过来解释了为什么循环不会终止。由于未读取任何数据,因此在每次循环迭代中都会打印先前的值。

回答by chux - Reinstate Monica

Do not compare against EOF, compare against the expected number of parsed fields.

不要与 EOF 进行比较,而是与已解析字段的预期数量进行比较。

while(3 == fscanf(input, " %49[^@ ]@%*49s -> %49[^@ ]@%49s", sender, receiver, trash)){
   printf("%s " "%s\n", sender, receiver);
}

Some minor changes

一些小改动

Suspect you may want to skip over any leading whitespace, so begin format with " ". ( I am sure this is contributing to your end-less loop. First scanning leave the \nin the input queue. 2nd scan won't put \ninto senderand fscanf()returns 0, which is not EOF. Vicious cycle repeats.)

怀疑您可能想要跳过任何前导空格,因此以" ". (我相信这是促使你最终少循环。首先扫描离开\n输入队列中。第二次扫描不会把\n进入senderfscanf()返回0,这是不是EOF。恶性循环重复。)

No need to saveyour first scanning of trash field with `"%49s". Use "*" to scan and not save.

无需使用 `"%49s"保存您对垃圾字段的第一次扫描。使用“*”扫描而不保存。

Scan the second trash field andsave to add to the scan count. This helps validate the incoming data is formatted as expected. An alternate pedantic check could be " %49[^@ ]@%*49s -> %49[^@ ]@%*49s%[\n].

扫描第二个垃圾场保存以添加到扫描计数中。这有助于验证传入数据的格式是否符合预期。一个替代的迂腐检查可能是" %49[^@ ]@%*49s -> %49[^@ ]@%*49s%[\n].

BTW, recommend using fgets()to get the line and use sscanf()to tear apart. Easier to handle I/O and parsing errors.

顺便说一句,建议fgets()用于获取线并用于sscanf()撕裂。更容易处理 I/O 和解析错误。

回答by Alexander L. Belikoff

fscanf()returns number of conversions made. EOFis only returned when the very firstconversion has failed. The proper way would be:

fscanf()返回进行的转换次数。EOF仅在第一次转换失败时返回。正确的方法是:

while (fscanf(fp, "...", &v1, &v2, ...) == <number_of_variables_read>) {
    ...
}

if (ferror(fp)) ...