本文介绍了与fgets()的fscanf后不工作()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的fscanf的日期来阅读并随后FGETS阅读笔记。
第一次迭代后然而,的fscanf返回值-1。

我用GDB调试一步的程序步骤。它工作正常,直到第一次使用与fgets的。当我尝试打印出通过对第一次迭代与fgets读行了,它给了我这样的:

 (GDB)打印行
$ 6 = \"\\rtest\\r18/04/2010\\rtest2\\r03/05/2010\\rtest3\\r05/08/2009\\rtest4\\r\
\\000\\000\\000\\000q\\352\\261\\a\\370\\366\\377\\267.N=\\366\\000\\000\\000\\000\\003\\000\\000\\000\\370xC\\000\\000\\000\\000\\000\\000\\000\\000\\000\\001\\000\\000\\000\\227\\b\\000\\000\\070\\367\\377\\267H\\364\\377\\267\\362\\202\\004\\bdoD\\000\\354\\201\\004\\b\\001\\000\\000\\000\\304oC\\000p\\363\\377\\277\\260zC\\000D\\363\\377\\277\
!B\\000\\064\\363\\377\\277\\354\\201\\004\\b(\\363\\377\\277TzC\\000\\000\\000\\000\\000\\070\\367\\377\\267\\001\\000\\000\\000\\000\\000\\000\\000\\001\\000\\000\\000\\370xC\\000\\001\\000\\000\\000\\000\\000\\312\\000\\000\\000\\000\\000\\377\\260\\360\\000\\001\\000\\000\\000\\277\\000\\000\\000\\364\\317\\000\\000\\344\\261\\\\\\000\\000\\000\\000\\000p\\363\\377\\277|\\233\\004\\b\\350\\362\\377\\277 \\ 204 \\ 004 \\ B \\ 005 \\ 000 \\ 000 \\ 000 | \\ 233 \\ 004 \\ B \\ 030 \\ 363 \\ 377 \\ 277

看起来与fgets读取剩余的条目,然后将它们存储在一个单一的字符串。

我不知道它为什么是这样做的。

下面是主要的code:

  INT主(INT ARGC,CHAR *的argv []){
    FILE *文件;
    INT numEntries,I = 0;
    INT指数=的atoi(ARGV [1]);
    焦线[SIZE]
    JournalEntry的*进入;    / *提供的参数是入门用户想要显示* /
    如果(argc个→2){
        PERROR(错误:提供的参数过多);
    }
    文件= FOPEN(journalentries.txt,R);
    如果(文件== NULL){
        PERROR(错误打开文件);
    }    如果(的fscanf(文件,%d个,&放大器;!numEntries)= 1){
        PERROR(无法读取的条目数);
    }    进入=(JournalEntry的*)malloc的(numEntries *的sizeof(JournalEntry的));
    如果(入门== NULL){
        PERROR(malloc的失败);
    }    对于(i = 0; I< numEntries;我++){
        如果(的fscanf(文件%D /%D /%D,&安培;进入[I]·天,和放大器;入门[I] .month,和放大器;!入门[I] .year)= 3){
            PERROR(无法读取入境日期);
        }        如果(与fgets(线,的sizeof(线),文件)== NULL){
            PERROR(无法读取入境文字);
        }
    }    的printf(%D-%02d-%02D%S:进入[指数] .year,进入[指数] .month,进入[指数]·天,进入[指数]的.text);    如果(FERROR(文件)){
        PERROR(错误与文件);
    }    FCLOSE(文件);
    免费入场);    返回0;
}

这是我要读文件:
的第一行包含要读取的条目数

  4
12/04/2010
测试
18/04/2010
TEST2
03/05/2010
TEST3
05/08/2009
TEST4

位于头文件中的结构JournalEntry的:

  typedef结构{
    日整型;
    INT月;
    INT年;
    字符文本[250];
} JournalEntry的;


解决方案

Yes, '\r' is not line terminator. So when fscanf stops parsing at the first invalid character, and leaves them in the buffer, then fgets will read them until end of line. And since there are no valid line terminators in the file, that is until end of file.

You should probably fix the file to have valid (Unix?) line endings, for example with suitable text editor which can do it. But that is another question, which has been asked before (like here), and depends on details not included in your question.

Additionally, you need dual check for fscanf return value. Use perror only if return value is -1, otherwise error message will not be related to the error at all. If return value is >=0 but different from what you wanted, then print custom error message "invalid input syntax" or whatever (and possibly use fgets to read rest of the line out of the buffer).

Also, to reliably mix scanf and fgets, I you need to add space in the fscanf format string, so it will read up any whitespace at the end of the line (also at the start of next line and any empty lines, so be careful if that matters), like this:

int items_read = scanf("%d ", &intvalue);

As stated in another answer, it's probably best to read lines with fgets only, then parse them with sscanf line-by-line.

这篇关于与fgets()的fscanf后不工作()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 10:32