我正在尝试从文本文件中填充数组。我正在使用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的字符。我做错了什么吗?
答案 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);
}
这是对内存代码的快速反应。我没有随时可用的编译器,但我认为它是正确的。