C从文本文件填充数组

时间:2013-08-06 22:35:03

标签: c arrays ansi fgetc

我正在尝试从文本文件中填充数组。我正在使用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 个答案:

答案 0 :(得分:1)

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

int c = fgetc(fp);

然后测试c的值。如果你想要存储它或再次循环它。

答案 1 :(得分: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()没什么经验。如果您发现我所做的事情非常糟糕,请通知我!

答案 2 :(得分:1)

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

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

有两次调用fgetc()。这意味着如果第一个调用没有返回'\ n',那么将进行另一个调用,然后将其返回值与'\ r'进行比较。这会使文件指针前进两次,因为每次调用fgetc时指针都会前进。更好的方法是获取一个字符,然后测试它是'\ n'还是'\ _ \',然后只有在另一次调用fgetc时才增加文件指针,如果这是真的话。例如:

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

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

答案 3 :(得分: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);
}

这是对内存代码的快速反应。我没有随时可用的编译器,但我认为它是正确的。