如何读取文本文件并将其内容存储到另一个字符串中?C

如何读取文本文件并将其内容存储到另一个字符串中?C,c,string,file,C,String,File,我想将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) {

我想将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);

fgets在读取换行符或EOF后停止。因此,您再次写入同一个缓冲区。

fgets在读取换行符或EOF后停止。因此,您再次写入同一个缓冲区。

读取

由于您希望一次读取整个文件,因此最好使用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);
忽略错误处理。

读取

由于您希望一次读取整个文件,因此最好使用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将用新的缓冲区替换旧的缓冲区,您必须将下一个缓冲区放在缓冲区指针的下一个偏移量中

#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);
}
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);
}

当您想在固定缓冲区中读取和追加行时,需要跟踪缓冲区中的位置以追加新字符,然后跟踪每次添加后可用的字符数。当您从输入流中读取行时,您不会在读取循环时设置条件!文件的数量。见:

相反,您可以根据正在使用的输入函数的返回来调节读取循环,也可以持续循环,在循环开始时检查输入函数的返回,当输入函数返回EOF或发生未处理的读取错误时中断循环。这两种方法基本上是等效的

对于256个字符的缓冲区,只需声明256个字符的数组进行存储,然后声明一个指向数组开头的指针,用于在缓冲区内写入新字符,将指针向前移动到写入的字符的末尾,以准备下次读取。读取要添加的字符时,您最多只能读取缓冲区中未使用的可用字符数。无论您是使用strcpy/strcat,还是只是在指针位置将字符读入缓冲区,跟踪剩余的可用字符都是一样的

在计算剩余的可用字符数时,唯一需要注意的是必须为nul终止字符保留存储空间。对于在缓冲区中构建的字符串,您只需要一个字符串,因此它与您添加到缓冲区的第一个字符串一起添加

<> >在加入字符串时,还需要考虑如何处理输入文件中的空空行。因为它们不会添加到要加入的字符串中,所以您可以直接跳到下一行,除非您想将它们保留在缓冲区中

当使用面向行的读取函数(如fgets或POSIX getline)时,还必须处理每次读取中包含的“\n”读取。连接字符串时处理包含的“\n”的简单方法是使用“”空格字符覆盖它,以便在缓冲区中相邻字符串之间提供空格

<> P>最后要考虑的是在退出读循环时从缓冲区的末尾删除最后的“空间”。用“”覆盖“\n”而产生的结果。只需减少正在使用的指针,并用nul终止字符覆盖最终的“”

$ ./bin/appendstr < dat/cake.txt
Hi there how are you do you like cake I love cake
总之,你可以做类似的事情:

#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/cakedbl.txt
Hi there how are you

do you like cake

I love cake
示例使用/输出

将文件中的所有行追加,并用最多MAXC-1个字符的空格分隔,为nul termianting字符留出空间

$ ./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方法使用单独的缓冲区进行读取和追加,以简化操作,但剩余可用字符的计算基本相同。

当您要将行读取和追加到固定缓冲区中时,您需要跟踪缓冲区中的位置以追加新字符,然后跟踪每次添加后可用的字符数。当您从输入流中读取行时,您不会在读取循环时设置条件!文件的数量。见:

相反,您可以根据正在使用的输入函数的返回来调节读取循环,也可以持续循环,在循环开始时检查输入函数的返回,当输入函数返回EOF或发生未处理的读取错误时中断循环。这两种方法基本上是等效的

对于256个字符的缓冲区,只需声明 存储256个字符的数组,然后声明指向数组开头的指针,用于在缓冲区中写入新字符,将指针向前移动到写入的字符的末尾,以准备下次读取。读取要添加的字符时,您最多只能读取缓冲区中未使用的可用字符数。无论您是使用strcpy/strcat,还是只是在指针位置将字符读入缓冲区,跟踪剩余的可用字符都是一样的

在计算剩余的可用字符数时,唯一需要注意的是必须为nul终止字符保留存储空间。对于在缓冲区中构建的字符串,您只需要一个字符串,因此它与您添加到缓冲区的第一个字符串一起添加

<> >在加入字符串时,还需要考虑如何处理输入文件中的空空行。因为它们不会添加到要加入的字符串中,所以您可以直接跳到下一行,除非您想将它们保留在缓冲区中

当使用面向行的读取函数(如fgets或POSIX getline)时,还必须处理每次读取中包含的“\n”读取。连接字符串时处理包含的“\n”的简单方法是使用“”空格字符覆盖它,以便在缓冲区中相邻字符串之间提供空格

<> P>最后要考虑的是在退出读循环时从缓冲区的末尾删除最后的“空间”。用“”覆盖“\n”而产生的结果。只需减少正在使用的指针,并用nul终止字符覆盖最终的“”

$ ./bin/appendstr < dat/cake.txt
Hi there how are you do you like cake I love cake
总之,你可以做类似的事情:

#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/cakedbl.txt
Hi there how are you

do you like cake

I love cake
示例使用/输出

将文件中的所有行追加,并用最多MAXC-1个字符的空格分隔,为nul termianting字符留出空间

$ ./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方法使用单独的缓冲区进行读取和追加,以简化操作,但剩余可用字符的计算基本上是相同的。

像feof这样的状态报告功能只会告诉您过去已经发生了什么。你不能用它们来预测未来——在这种情况下,对尚未发生的fgets的调用是否会遇到文件结尾。状态报告功能(如feof)只会告诉你过去已经发生了什么。您不能使用它们来预测未来——在这种情况下,对尚未发生的FGET的调用是否会遇到文件的结尾。ptr+=strlenptr;渲染fgetsptr中的256,256,fp;无意义。@DavidRankin不,fgets不能保证渲染256字节,它只会在到达换行符之前渲染\n。但是,这是不安全的,因为如果文件大小超过256字节,则可能会发生溢出。此时,在buf中推进ptr后,将不再剩下256个字符。因此,在下次调用fgets.ptr+=strlenptr之前,需要从256个字符中减去使用的字符数;渲染fgetsptr中的256,256,fp;无意义。@DavidRankin不,fgets不能保证渲染256字节,它只会在到达换行符之前渲染\n。但是,这是不安全的,因为如果文件大小超过256字节,则可能会发生溢出。此时,在buf中推进ptr后,将不再剩下256个字符。因此,在下次调用fgets之前,需要从256个字符中减去使用的字符数。