[英]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);
由於您想一次讀取整個文件,因此最好使用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
如果您還有其他問題,請仔細查看並告訴我。 使用strcpy
和strcat
重寫程序以連接字符串。 (您會發現使用單個緩沖區時它基本上是一種洗滌)。 您可以使用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.