如何读取文本文件并将其内容存储到另一个字符串中?C
我想将file.txt的内容复制到字符串buf中。当我运行这个程序时,它似乎只打印出“我爱蛋糕”这几个字 file.txt的内容位于此行下方 你好,你好吗 你喜欢蛋糕吗 我喜欢蛋糕如何读取文本文件并将其内容存储到另一个字符串中?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) {
//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个字符中减去使用的字符数。