问题描述
|
我正在尝试通过给函数提供行号作为参数来将文本文件上的行读入缓冲区。然后,此函数将文件特定行中包含的文本复制到变量“ 0”中以供使用。我遇到的问题是,如果文本文件的末尾没有“空换行符”,则程序不会将最后一个条目复制到缓冲区中。我究竟做错了什么?。
正确读取的文本文件示例
0行
1行
没有在最后一行读入缓冲区(即第1行)的文本文件示例。
0行
1行
//test2
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 80
char read_in_buffer[BUFFER_SIZE];
char retreivedString[BUFFER_SIZE];
void getString(int lineNum);
int maxDatanum = 0;
bool endOfFileReached = false;
int main(void){
printf(\"-Main-\\n\");
getString(1);
printf(\"retrieved:%s\\n\",retreivedString);
printf(\"maxdata: %d\\n\",maxDatanum);
printf(\"strlen: %d\",strlen(retreivedString));
/*
getString(2);
printf(\"retrieved: %s\\n\",maxDatanum);
getString(4);
printf(\"retrieved: %s\\n\",maxDatanum);
*/
return 0;
}
void getString(int lineNum){
FILE *fin=fopen(\"file1_Windows.txt\",\"r\");
int line_number = 0;
char *temp;
if(fin==NULL){
printf(\"cannot open file1_Windows.txt\\n\");
}
while (1){
memset(read_in_buffer,sizeof(read_in_buffer));
fgets(read_in_buffer,sizeof(read_in_buffer),fin); //change to segment size?
if (!feof(fin)) {
if (lineNum == line_number){
memset(retreivedString,sizeof(retreivedString));
strcpy(retreivedString,read_in_buffer);
}
//printf(\"current line %d: \",line_number);
//printf(\"%s\",read_in_buffer);
line_number++;
}else {
fclose(fin);
printf(\"End-of-File reached. \\n\");
maxDatanum = line_number;
printf(\"maxdata: %d\\n\",maxDatanum);
if (lineNum == maxDatanum){
endOfFileReached = true;
}else if (lineNum > maxDatanum){
printf(\"file read error,you\'re reading further that data on file\\n\");
}
break;
}
}
}
解决方法
做这个。如果
fopen
调用失败,它将返回并将fgets
调用放入while循环中:
void getString(int lineNum){
FILE *fin=fopen(\"file1_Windows.txt\",\"r\");
int line_number = 0;
char *temp;
if(fin==NULL){
printf(\"cannot open file1_Windows.txt\\n\");
return;
}
memset(read_in_buffer,sizeof(read_in_buffer));
while (fgets(read_in_buffer,sizeof(read_in_buffer),fin) != NULL){
if (lineNum == line_number){
memset(retreivedString,sizeof(retreivedString));
strcpy(retreivedString,read_in_buffer);
}
//printf(\"current line %d: \",line_number);
//printf(\"%s\",read_in_buffer);
line_number++;
memset(read_in_buffer,sizeof(read_in_buffer));
}
fclose(fin);
printf(\"End-of-File reached. \\n\");
maxDataNum = line_number;
printf(\"maxdata: %d\\n\",maxDataNum);
if (lineNum == maxDataNum){
endOfFileReached = true;
}else if (lineNum > maxDataNum){
printf(\"file read error,you\'re reading further that data on file\\n\");
}
}
,而不是在while循环中测试feof
(请参阅此线程,原因是不这样做),而是测试read_in_buffer
是否为空,因为一旦您用完了要读取的行,该指针就会变为空。您甚至可以将fgets作为if语句主体:
if (fgets(read_in_buffer,fin))
{
}
,以下是有关fgets的标准说明:
概要
char *fgets(char * restrict s,int n,FILE * restrict stream);
描述
fgets函数最多读取一个
少于字符数
由指向的流中的n指定
通过流进入指向的数组
由s。没有其他字符
在换行符(其中
保留)或文件结束后。一种
空字符立即被写入
最后一个字符读入后
数组。
退货
如果以下情况,fgets函数返回s
成功。如果文件结尾为
遇到并且没有字符
被读入数组,内容
的数组保持不变,并且
返回空指针。如果读
操作过程中发生错误,
数组内容不确定,并且
返回空指针。
因此,发生了以下情况:
读取最后一行时,fgets返回read_in_buffer(不是null指针),因为存在已读取的字符并且没有发生读取错误。
然后,检查feof(fin)返回true(因为已经达到EOF),从而使该代码从不执行:strcpy(retreivedString,read_in_buffer)。
结论:
retreivedString永远不会被修改,并且因为它是一个全局变量,所以它使用0位(等效于一个空字符串)进行了初始化。
因此,如果您打印retreivedString,则输出将为空字符串。
,将fgets()行放入if()条件中。毕竟,只有在未设置EOF的情况下,您才想从文件中读取内容。
if (!feof(fin)) {
line_number++;
fgets(read_in_buffer,fin);
...
}