读取文件并在 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 );
}