读取文件并在 C 中打印内容
Reading a file and print the content in C
我正在学习如何用 C 编写和读取文件,我用这段代码写了一篇文章
FILE *f = fopen("testingText.txt", "w");
char *text = "This is text1...";
fwrite(text, sizeof(char), strlen(text), f );
fclose(f);
当我读取此文件的内容并使用此代码打印时
FILE *f = fopen("testingText.txt", "r");
fseek(f, 0, SEEK_END);
unsigned int size = ftell(f);
fseek(f , 0, SEEK_SET);
char *content = (char *)malloc(size);
fread(content, sizeof(char), size, f);
printf("File content is...\n%s", content);
free(content);
fclose(f);
它给出了类似这些奇怪的结果
文件内容是...
这是 text1...Path=C:*┬#æ╩eò*
当我再次 运行 代码时,它给出了不同的奇怪的东西。
文件中没有 null terminator,因此您需要在打印从文件中读取的内容之前手动添加它。
示例:
char *content = malloc(size + 1); // +1 for the null terminator
size_t chars_read = fread(content, 1, size, f); // store the returned value
content[chars_read] = '[=10=]'; // add null terminator
printf("File content is...\n%s\n", content); // now ok to print
下面一行是错误的:
printf("File content is...\n%s", content);
将 printf
与 %s
转换格式说明符一起使用需要一个以 null 结尾的字符串。但是,您的字符串不是以 null 结尾的。
为了打印不以 null 结尾的字符序列,您可以改为编写以下内容:
printf( "File content is...\n%.*s", (int)size, content );
或者您可以使用以下行手动添加终止空字符:
content[size] = '[=12=]';
但是,这将越界写入内存缓冲区 content
,因为您没有为空终止字符分配任何 space。因此,您应该在 malloc
函数调用中分配一个额外的字节。
另一个问题是使用ftell
不是确定文件长度的可靠方法。 ISO C 标准不保证这会起作用。
例如,在 Microsoft Windows 上,这将为您提供二进制模式下的文件长度(即使文件以文本模式打开)。但是,文本模式下文件的长度不同,因为 \r\n
行结尾在 Microsoft Windows.
上被转换为 \n
因此,如果要读取未知长度的文本文件的内容,最好是循环一次读取一行,使用函数fgets
:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
FILE *fp;
char line[100];
//attempt to open file
fp = fopen( "testingText.txt", "r" );
//verify that file is open
if ( fp == NULL )
{
fprintf( stderr, "error opening file!\n" );
exit( EXIT_FAILURE );
}
printf( "File content is...\n" );
//print one line per loop iteration
while ( fgets( line, sizeof line, fp ) != NULL )
{
//the following code will work even if "fgets" only
//reads a partial line, due to the input buffer not
//being large enough
//print the line to standard output
fputs( line, stdout );
}
//cleanup
fclose( fp );
}
我正在学习如何用 C 编写和读取文件,我用这段代码写了一篇文章
FILE *f = fopen("testingText.txt", "w");
char *text = "This is text1...";
fwrite(text, sizeof(char), strlen(text), f );
fclose(f);
当我读取此文件的内容并使用此代码打印时
FILE *f = fopen("testingText.txt", "r");
fseek(f, 0, SEEK_END);
unsigned int size = ftell(f);
fseek(f , 0, SEEK_SET);
char *content = (char *)malloc(size);
fread(content, sizeof(char), size, f);
printf("File content is...\n%s", content);
free(content);
fclose(f);
它给出了类似这些奇怪的结果
文件内容是... 这是 text1...Path=C:*┬#æ╩eò*
当我再次 运行 代码时,它给出了不同的奇怪的东西。
文件中没有 null terminator,因此您需要在打印从文件中读取的内容之前手动添加它。
示例:
char *content = malloc(size + 1); // +1 for the null terminator
size_t chars_read = fread(content, 1, size, f); // store the returned value
content[chars_read] = '[=10=]'; // add null terminator
printf("File content is...\n%s\n", content); // now ok to print
下面一行是错误的:
printf("File content is...\n%s", content);
将 printf
与 %s
转换格式说明符一起使用需要一个以 null 结尾的字符串。但是,您的字符串不是以 null 结尾的。
为了打印不以 null 结尾的字符序列,您可以改为编写以下内容:
printf( "File content is...\n%.*s", (int)size, content );
或者您可以使用以下行手动添加终止空字符:
content[size] = '[=12=]';
但是,这将越界写入内存缓冲区 content
,因为您没有为空终止字符分配任何 space。因此,您应该在 malloc
函数调用中分配一个额外的字节。
另一个问题是使用ftell
不是确定文件长度的可靠方法。 ISO C 标准不保证这会起作用。
例如,在 Microsoft Windows 上,这将为您提供二进制模式下的文件长度(即使文件以文本模式打开)。但是,文本模式下文件的长度不同,因为 \r\n
行结尾在 Microsoft Windows.
\n
因此,如果要读取未知长度的文本文件的内容,最好是循环一次读取一行,使用函数fgets
:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
FILE *fp;
char line[100];
//attempt to open file
fp = fopen( "testingText.txt", "r" );
//verify that file is open
if ( fp == NULL )
{
fprintf( stderr, "error opening file!\n" );
exit( EXIT_FAILURE );
}
printf( "File content is...\n" );
//print one line per loop iteration
while ( fgets( line, sizeof line, fp ) != NULL )
{
//the following code will work even if "fgets" only
//reads a partial line, due to the input buffer not
//being large enough
//print the line to standard output
fputs( line, stdout );
}
//cleanup
fclose( fp );
}