簡體   English   中英

如何讀取文本文件並將其內容存儲到另一個字符串中? C

[英]How do I read a text file and store its content into another string? C

我想將“file.txt”的內容復制到字符串“buf”中。 當我運行程序時,它似乎只打印出“我愛蛋糕”的字樣。

file.txt 的內容在這一行下面

嘿,你好嗎

你喜歡蛋糕嗎

我喜歡蛋糕

//Variable Declarations
char buf[256] = "";
char dest[256] = "";


//Check if the file exists
FILE* fp;
fopen_s(&fp ,"file.txt", "r");
if (fp != NULL) {
    printf("File has been opened\n");
}
else
{
    printf("File did not open\n");
}

while (!feof(fp)) 
{
    fgets(buf, 256, fp);
}


printf("%s\n", buf);

閱讀while (!feof(fp))總是錯誤的。

由於您想一次讀取整個文件,因此最好使用fread ,以讀取模式(非二進制)打開文件:

FILE *fp = . . .;

fseek(fp, 0, SEEK_END);
long n = ftell(fp);
rewind(fp);

char *buf = malloc(n+1);
fread(fp, buf, 1, n);
buf[n] = 0;

fclose(fp);

省略了錯誤處理。

fgets 在讀取換行符或 EOF 后停止。 所以你再次寫入同一個緩沖區。

當您想將 append 行讀取到固定緩沖區時,您需要跟蹤緩沖區中的 position 到 append 新字符以及每次添加后可用的字符數。 當您從輸入 stream 讀取行時,您不會將讀取循環設置為while (!feof (file)) (請參閱: 為什么 while (?feof (file) ) 總是錯誤的?

相反,您可以根據正在使用的輸入 function的返回來調節您的讀取循環,或者您不斷循環,在循環的開頭檢查輸入 function 的返回,當您的輸入 ZC1C4245268E68AB584F11 返回EOF發生您未處理的讀取錯誤)這兩種方法本質上是等效的。

對於256字符緩沖區的情況,您可以簡單地聲明256字符數組進行存儲,然后聲明一個指向數組開頭的指針,您將使用該指針在緩沖區中寫入新字符,將指針推進到寫入對象的末尾准備下一次閱讀。 讀取要添加的字符時,您最多只能讀取緩沖區中未使用的可用字符數。 無論您是使用strcpy/strcat還是只是在指針位置將字符讀入緩沖區都沒關系——跟蹤剩余的可用字符是相同的。

計算剩余可用字符數時唯一需要注意的是,您必須為nul 終止字符保留存儲空間。 您只需要一個用於在緩沖區中構建的字符串,因此它與您添加到緩沖區的第一個字符串一起添加。

連接字符串時,您還需要考慮如何處理輸入文件中的空白(空)行。 由於它們不會添加到您要加入的字符串中,您可以直接跳到下一行 - 除非您想將它們保留在緩沖區中。

當使用面向行的讀取 function (如fgets()或 POSIX getline()時,您還必須處理'\n'讀取並包含在每次讀取中。 連接字符串時處理包含'\n'的簡單方法是用' ' (空格)字符覆蓋它,以便在緩沖區中的相鄰字符串之間提供一個空格。

最后要考慮的是在退出讀取循環時從緩沖區末尾刪除最后' ' (空格)。 (用' '覆蓋'\n'的結果)。 只需遞減您正在使用的指針,並用nul 終止字符覆蓋最后' '

總而言之,您可以執行以下操作:

#include <stdio.h>
#include <string.h>

#define MAXC 256    /* if you need a constant, #define one (or more) */

int main (void) {

    char buf[MAXC], *p = buf;   /* buffer and pointer to buffer  */
    size_t avail = MAXC;        /* character avaialble in buffer */

    while (fgets (p, avail, stdin)) {   /* read up to avail characters */
        size_t len = strlen(p);         /* get length read */
        if (*p == '\n')                 /* ignore blank lines in input */
            continue;
        if (len && p[len-1] == '\n')    /* overwrite \n with space */
            p[len-1] = ' ';
        p += len;                       /* advance len chars in buf */
        /* subtract len chars from avail (len + 1 chars 1st iteration) */
        avail -= (avail == MAXC) ? len + 1 : len;
    }
    if (*--p == ' ')    /* backup over space at end and nul-terminate */
        *p = 0;

    puts (buf);     /* output combined string */
}

注意:處理前導空格、多個中間空格或尾隨空格留給您)

示例輸入文件

$ cat dat/cake.txt
Hi there how are you
do you like cake
I love cake

或帶有空行的文件:

$ cat dat/cakedbl.txt
Hi there how are you

do you like cake

I love cake

示例使用/輸出

Append 文件中的所有行由空格分隔,最多MAXC - 1字符(為空終止字符留出空間)。

$ ./bin/appendstr < dat/cake.txt
Hi there how are you do you like cake I love cake

雙倍行距文件。

$ ./bin/appendstr < dat/cakedbl.txt
Hi there how are you do you like cake I love cake

如果您還有其他問題,請仔細查看並告訴我。 使用strcpystrcat重寫程序以連接字符串。 (您會發現使用單個緩沖區時它基本上是一種洗滌)。 您可以使用strcpy/strcat方法使用單獨的緩沖區進行讀取和追加以簡化事情,但剩余可用字符的計算基本上是相同的。

fgets將用新緩沖區替換舊緩沖區,您必須將下一個緩沖區放在緩沖區指針的下一個偏移量中。

#include <stdio.h>
#include <string.h>

int main()
{
    //Variable Declarations
    char buf[256] = "";
    char dest[256] = "";
    char *ptr = buf;


    //Check if the file exists
    FILE* fp;
    fp = fopen("file.txt", "r");
    if (fp != NULL) {
        printf("File has been opened\n");
    }
    else
    {
        printf("File did not open\n");
    }

    while (!feof(fp)) 
    {
        fgets(ptr, 256, fp);
        ptr += strlen(ptr);
    }


    printf("%s\n", buf);
}

暫無
暫無

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

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