简体   繁体   English

fread 和 fgets 的规格之间的区别?

[英]Difference between specifications of fread and fgets?

What is the difference between fread and fgets when reading in from a file?从文件读入时 fread 和 fgets 有什么区别? I use the same fwrite statement, however when I use fgets to read in a .txt file it works as intended, but when I use fread() it does not.我使用相同的 fwrite 语句,但是当我使用 fgets 读取 .txt 文件时,它按预期工作,但是当我使用 fread() 时却没有。

I've switched from fgets/fputs to fread/fwrite when reading from and to a file.在读取和读取文件时,我已从 fgets/fputs 切换到 fread/fwrite。 I've used fopen(rb/wb) to read in binary rather than standard characters.我使用 fopen(rb/wb) 读取二进制而不是标准字符。 I understand that fread will get /0 Null bytes as well rather than just single lines.我知道 fread 也会得到 /0 Null 字节,而不仅仅是单行。

  //while (fgets(buff,1023,fpinput) != NULL) //read in from file
  while (fread(buff, 1, 1023, fpinput) != 0) // read from file

I expect to read in from a file to a buffer, put the buffer in shared memory, and then have another process read from shared memory and write to a new file.我希望从文件读入缓冲区,将缓冲区放入共享内存中,然后让另一个进程从共享内存中读取并写入新文件。

When I use fgets() it works as intended with .txt files, but when using fread it adds a single line from 300~ characters into the buffer with a new line.当我使用 fgets() 时,它可以按预期与 .txt 文件一起工作,但是当使用 fread 时,它将一行 300~ 个字符的单行添加到缓冲区中并换行。 Can't for the life of me figure out why.不能为我的生活弄清楚为什么。

fgets will stop when encountering a newline. fgets会在遇到换行符时停止。 fread does not. fread没有。 So fgets is typically only useful for text files, while fread can be used for both text and binary files.所以fgets通常只对文本文件有用,而fread可用于文本和二进制文件。

From the C11 standard:来自 C11 标准:

7.21.7.2 The fgets function 7.21.7.2 fgets 函数

The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. fgets 函数从 stream 指向的流中读取至多比 n 指定的字符数少 1 到 s 指向的数组中。 No additional characters are read after a new-line character (which is retained) or after end-of-file.在换行符(保留)后或文件结束后不会读取其他字符。 A null character is written immediately after the last character read into the array.在读入数组的最后一个字符后立即写入空字符。

7.21.8.1 The fread function 7.21.8.1 fread 函数

The fread function reads, into the array pointed to by ptr, up to nmemb elements whose size is specified by size, from the stream pointed to by stream. fread 函数从 stream 所指向的流中将最多大小由 size 指定的 nmemb 元素读入 ptr 所指向的数组中。 For each object, size calls are made to the fgetc function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object.对于每个对象,都会对 fgetc 函数进行 size 调用,并将结果按读取顺序存储在正好覆盖该对象的无符号字符数组中。 The file position indicator for the stream (if defined) is advanced by the number of characters successfully read.流的文件位置指示符(如果已定义)按成功读取的字符数前进。 If an error occurs, the resulting value of the file position indicator for the stream is indeterminate.如果发生错误,则流的文件位置指示符的结果值是不确定的。 If a partial element is read, its value is indeterminate.如果读取了部分元素,则其值是不确定的。

This snippet maybe will make things clearer for you.这个片段可能会让你更清楚。 It just copies a file in chunks.它只是分块复制文件。

#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 {
        // fread returns the number of successfully read elements
        bytes_read = fread(buffer, 1, chunk_size, in);

        /* Insert any modifications you may */
        /* want to do here                  */

        // write bytes_read bytes from buffer to output file
        if(fwrite(buffer, 1, bytes_read, out) != bytes_read) exit(EXIT_FAILURE);
   // When we read less than chunk_size we are either done or an error has 
   // occured. This error is not handled in this program. 
    } while(bytes_read == chunk_size); 


    free(buffer);
    fclose(out);
    fclose(in);
}

You mentioned in a comment below that you wanted to use this for byteswapping.您在下面的评论中提到您想将其用于字节交换。 Well, you can just use the following snippet.好吧,您可以只使用以下代码段。 Just insert it where indicated in code above.只需将其插入到上面代码中指示的位置即可。

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM