簡體   English   中英

將文本讀入 c 中的緩沖區。 (當文本文件上沒有換行符時,省略最后一行數據)

[英]Reading text into a buffer in c. (leaves out the last line of data when there is no newline on the textfile)

我試圖通過給 function 一個行號作為參數來將文本文件上的行讀入緩沖區。 然后,此 function 將文件特定行中包含的文本復制到變量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:%s\n",retreivedString);
        printf("maxdata: %d\n",maxDataNum);
        printf("strlen: %d",strlen(retreivedString));
        /*
        getString(2);
        printf("retrieved: %s\n",retreivedString);
        printf("maxdata: %d\n",maxDataNum);
        getString(4);
        printf("retrieved: %s\n",retreivedString);
        printf("maxdata: %d\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,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: %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,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: %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是否為 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 function 從 stream 指向的 stream 中讀取最多比 n 指定的字符數少一個到 s 指向的數組中。 在換行符(保留)之后或文件結尾之后不會讀取其他字符。 在讀入數組的最后一個字符之后立即寫入 null 字符。

退貨

如果成功,fgets function 返回 s。 如果遇到文件結尾並且沒有字符被讀入數組,則數組的內容保持不變並返回 null 指針。 如果在操作過程中發生讀取錯誤,則數組內容不確定,並返回 null 指針。

所以,這就是發生的事情:

  1. 讀取最后一行時,fgets返回read_in_buffer不是null指針),因為有字符讀取,沒有出現讀取錯誤。
  2. 然后檢查feof(fin)返回 true (因為已經達到 EOF),這使得這段代碼永遠不會執行: strcpy(retreivedString,read_in_buffer)

結論:

  • retreivedString永遠不會被修改,因為它是一個全局變量,它被初始化為 0 位(相當於一個空字符串)。

因此,如果您打印retreivedString ,則 output 將是一個空字符串。

將 fgets() 行放在 if() 條件中。 畢竟,只有在未設置 EOF 的情況下,您才想從文件中讀取某些內容。

if (!feof(fin)) {
    line_number++;
    fgets(read_in_buffer,sizeof(read_in_buffer),fin);  
    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM