0

我正在尝试从文本文件中填充数组。我正在使用 fgetc,我的问题是处理文本文件中的换行符。我目前有,

for(i = 0; i < rows; i++){
    for(j = 0; j < columns; j++){
        if((fgetc(fp) == '\n') || (fgetc(fp) == '\r')){
            fgetc(fp); 
            array[i][j] = fgetc(fp);    
        else{
            array[i][j] = fgetc(fp); 
        }
        printf("i %d j %d char %c code %d\n", i, j, array[i][j], array[i][j]); 
     }
}

这个想法是,如果有一个换行符,我想在循环的相同 i,j 位置推进文件指针,这样我就可以获得下一个字符。前两行的输出是混乱的,然后它开始读取字符代码为 -1 的字符。我做错了什么吗?

4

4 回答 4

1

每次调用 fgetc 都会使文件指针前进。尝试调用一次:

int c = fgetc(fp);

然后测试c的值。如果需要,可以存储它或再次循环。

于 2013-08-06T22:45:08.853 回答
1

在你的第一个if()陈述中,有一点问题。当你这样做时:

if((fgetc(fp) == '\n') || (fgetc(fp) == '\r')){
        fgetc(fp); 
        array[i][j] = fgetc(fp); 

你实际上打fgetc(fp)了四次电话。在 if() 语句中两次,稍后两次。也许您正在寻找更多类似这样的东西:

for(i = 0; i < rows; i++){
    for(j = 0; j < columns; j++){
        int test = fgetc(fp);
        if(test != '\n' && test != '\r')
            array[i][j] = test;
        //We want to "undo" the last j++ if we got a whitespace
        else
            j--;
        printf("i %d j %d char %c code %d\n", i, j, array[i][j], array[i][j]); 
     }
}

在此示例中,fgetc(fp)每次迭代只调用一次,如果它不是 \n 或 \r,则将其放入数组中。

对不起,我没有什么经验fgetc()。如果您发现我所做的事情令人难以置信的糟糕,请通知我!

于 2013-08-06T22:47:05.423 回答
1

我可以立即看到一个错误来源。在以下行中:

if((fgetc(fp) == '\n') || (fgetc(fp) == '\r'))

fgetc() 有 2 次调用。这意味着如果第一次调用没有返回 '\n',将进行另一个调用,然后将其返回值与 '\r' 进行比较。这具有将文件指针推进两次的效果,因为每次调用 fgetc 时指针都会推进。更好的方法是获取一个字符,然后测试它是 '\n' 还是 '\r',然后再通过对 fgetc 的另一个调用来增加文件指针,如果这是真的。例如:

char letter = fgetc(fp);
if((letter == '\n') || (letter == '\r')
...
...

试试这个,看看你是否仍然得到同样的错误。

于 2013-08-06T22:47:09.517 回答
1

我相信您在评估声明中两次获得该角色。此外,通常 CRLF(回车和换行)行尾字符可以是两个字符。有关详细信息,请阅读http://en.wikipedia.org/wiki/Newline

#include <stdio.h>

int main ()
{
   FILE *fp;
   int c;

   fp = fopen("file.txt","r");
   if(fp == NULL) 
   {
      fprintf(stderr,"Error opening file");
      return(-1);
   }
   do
   {
      c = fgetc(fp);
      if ((c == '\n') || (c == '\r')) {
        fgetc(fp); // skip CR or LF and advance a character
      } else {
        printf("%c", c); // print all other characters
      }
   }while(c != EOF);

   fclose(fp);

   return(0);
}

这是对内存代码的快速打击。我没有现成的编译器,但我认为它是正确的。

于 2013-08-06T22:48:18.713 回答