我试图通过给函数一个行号作为参数,将文本文件上的行读取到缓冲区中。然后,此函数将文件的特定行中包含的文本复制到变量retreiveString
中以供使用。我遇到的问题是,如果文本文件的最后没有"空换行符",程序就不会将最后一个条目复制到缓冲区中。我做错了什么?。
正确读取的文本文件示例
第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:%sn",retreivedString);
printf("maxdata: %dn",maxDataNum);
printf("strlen: %d",strlen(retreivedString));
/*
getString(2);
printf("retrieved: %sn",retreivedString);
printf("maxdata: %dn",maxDataNum);
getString(4);
printf("retrieved: %sn",retreivedString);
printf("maxdata: %dn",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.txtn");
}
while (1){
memset(read_in_buffer,0,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,0,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: %dn",maxDataNum);
if (lineNum == maxDataNum){
endOfFileReached = true;
}else if (lineNum > maxDataNum){
printf("file read error, you're reading further that data on filen");
}
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.txtn");
return;
}
memset(read_in_buffer,0,sizeof(read_in_buffer));
while (fgets(read_in_buffer,sizeof(read_in_buffer),fin) != NULL){
if (lineNum == line_number){
memset(retreivedString,0,sizeof(retreivedString));
strcpy(retreivedString,read_in_buffer);
}
//printf("current line %d: ",line_number);
//printf("%s",read_in_buffer);
line_number++;
memset(read_in_buffer,0,sizeof(read_in_buffer));
}
fclose(fin);
printf("End-of-File reached. n");
maxDataNum = line_number;
printf("maxdata: %dn",maxDataNum);
if (lineNum == maxDataNum){
endOfFileReached = true;
}else if (lineNum > maxDataNum){
printf("file read error, you're reading further that data on filen");
}
}
与其在while循环中测试feof
(请参阅此线程以了解不测试的原因),不如测试read_in_buffer
是否为null,因为一旦您用完了要读取的行,指针就会变为null。你甚至可以把你的fgets作为if语句的主体:
if (fgets(read_in_buffer,sizeof(read_in_buffer),fin))
{
}
以下是关于fgets的标准:
简介
char *fgets(char * restrict s, int n, FILE * restrict stream);
描述
fgets函数最多读取一个少于字符数由n从指向的流中指定按流进入指向的数组by s。没有其他字符在换行符后读取(保留)或在文件结束之后。A.立即写入空字符在最后一个字符读入大堆
退货
fgets函数返回s if成功的如果文件结尾为遇到并且没有字符已读取到数组中,内容的值保持不变返回空指针。如果读取操作过程中发生错误数组内容不确定,并且返回空指针。
因此,发生的情况如下:
- 读取最后一行时,fgets返回read_in_buffer(非空指针),因为读取了字符并且没有发生读取错误
- 然后检查feof(fin)返回true(因为EOF已经达到),这使得此代码从未执行:strcpy(retivedString,read_in_buffer)
结论:
- RetrivedString从未被修改,因为它是一个全局变量,所以它被初始化为0位(相当于一个空字符串)
因此,如果打印retivedString,输出将是一个空字符串。
将fgets()行放入if()条件中。毕竟,只有在未设置EOF的情况下,您才想从文件中读取某些内容。
if (!feof(fin)) {
line_number++;
fgets(read_in_buffer,sizeof(read_in_buffer),fin);
...
}