file io-将文本读取到c中的缓冲区中(当文本文件上没有换行符时,会漏掉最后一行数据)



我试图通过给函数一个行号作为参数,将文本文件上的行读取到缓冲区中。然后,此函数将文件的特定行中包含的文本复制到变量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成功的如果文件结尾为遇到并且没有字符已读取到数组中,内容的值保持不变返回空指针。如果读取操作过程中发生错误数组内容不确定,并且返回空指针。

因此,发生的情况如下:

  1. 读取最后一行时,fgets返回read_in_buffer非空指针),因为读取了字符并且没有发生读取错误
  2. 然后检查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);  
    ...
}

最新更新