消除 freads 中的缓冲区溢出 (C)

问题描述

简单的问题,但由于要求有点奇怪。

基本上,当我读取文件使用文件 I/O 时,我试图防止缓冲区溢出,因为我正在读取缓冲区大小为 32 的文件。我觉得这应该在某处得到回答,但终生我的搜索没有打开。

我的代码的简化版本在这里

#include <stdio.h>                
#include <string.h>               
#define BUFFER_SIZE 32              
 
int main(int argc,char *argv[]) {
    FILE * read_file;
       
    char buffer[BUFFER_SIZE];
    read_file = fopen("test.txt","r");
    
    size_t num_rec = BUFFER_SIZE;
    while(fread(buffer,1,num_rec,read_file) > 0) {
        printf("%s",buffer);
    }
    fclose(read_file);
    
    return 0;
}

假设我正在尝试读取包含内容的 test.txt:

This is a test file. 
The file is a test. 
I am having an overflow problem.
My C is not the best.

我得到这样的输出

This is a test file.                                                                                                                                                               
The file is a test.                                                                                                                                                                
I am having an overflow problem.                                                                                                                                                   
My C is not the best.w problem.                                                                                                                                                    
My C is not the best

我知道解决这个问题的最简单方法是一次读取 1 个字符而不是 32 个字符,但是,有没有办法解决这个问题,同时仍然一次读取 32 个字符?

解决方法

下面保存fread的返回值,然后用它来printf已经读过的字符,仅此而已。

    size_t read_bytes;
    while((read_bytes = fread(buffer,1,num_rec,read_file)) > 0) {
        printf("%.*s",(int)read_bytes,buffer);
    }
,

fread() 函数读取二进制数据并且不添加空字节。您需要告诉 printf() 要打印多少字节,这应该是 fread() 返回的数字。

size_t nbytes;
while((nbytes = fread(buffer,read_file)) > 0)
    printf("%.*s",(int)nbytes,buffer);

请注意,fread() 返回一个 size_t,但 printf() 中的 .* 操作需要一个 int;因此是强制转换(尽管可以将来自 fread() 的值保存在 int 中并在没有强制转换的情况下使用它)。