fgets
在遇到换行符时会停止读取。而fread
则不会。因此,fgets
通常只对文本文件有用,而fread
可用于文本和二进制文件。
根据C11标准:
7.21.7.2 fgets函数
fgets函数从指向流的指针stream所指向的流中最多读取n个字符减1个字符,并将其存储到指向数组s的指针中。在新行字符(保留)或文件结束后,不会再读取任何其他字符。一个空字符会被写入到数组中最后一个读取的字符之后。
7.21.8.1 fread函数
fread函数从流指针stream指向的流中读取大小为size的元素,最多读取nmemb个元素,并将结果存储在由ptr指向的数组中。对于每个对象,fgetc函数会调用size次,并将以读取顺序存储的结果存储在无符号字符数组中,该数组恰好覆盖该对象。如果定义了流的文件位置指示器,则该指示器将根据成功读取的字符数进行提升。如果发生错误,则流的文件位置指示器的结果值是不确定的。如果只读取了部分元素,则其值是不确定的。
这段代码片段可能会让您更清楚地理解它。它只是将文件按块复制。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
if(argc != 3) {
printf("Usage: ./a.out src dst\n");
printf("Copies file src to dst\n");
exit(EXIT_SUCCESS);
}
const size_t chunk_size = 1024;
FILE *in, *out;
if(! (in = fopen(argv[1], "rb"))) exit(EXIT_FAILURE);
if(! (out = fopen(argv[2], "wb"))) exit(EXIT_FAILURE);
char * buffer;
if(! (buffer = malloc(chunk_size))) exit(EXIT_FAILURE);
size_t bytes_read;
do {
bytes_read = fread(buffer, 1, chunk_size, in);
if(fwrite(buffer, 1, bytes_read, out) != bytes_read) exit(EXIT_FAILURE);
} while(bytes_read == chunk_size);
free(buffer);
fclose(out);
fclose(in);
}
您在下面的评论中提到想要将其用于字节交换。那么,您可以使用以下代码片段。只需将其插入上面的代码中指定的位置即可。
for(int i=0; i < bytes_read - bytes_read%2; i+=2) {
char tmp = buffer[i];
buffer[i] = buffer[i+1];
buffer[i+1] = tmp;
}
fgets
遇到换行符时停止读取。fread
不会检查这些换行符。 - ikegamifgets
会添加一个 NUL 字符,而fread
则不会。 - ikegamifread
时,必须记住并使用读取的单位数,而不仅仅是检查是否为0
。但是,除非您只想将文本文件未经处理地复制到另一个文件中,否则fread
对于文本文件并不是很有用。 - Weather Vane