C 如何在程序中正确使用fread()和fwrite()?

C 如何在程序中正确使用fread()和fwrite()?,c,file,io,fwrite,fread,C,File,Io,Fwrite,Fread,你好。根据一个C Primer Plus示例,我编写了一个程序,可以附加 将用户指定的文件复制到主文件。起初,我写它只是为了和你一起使用 文本文件,但后来我把它改为二进制模式。我用它附加了四个文件。我得到了一些非常奇怪的结果,我不知道为什么。这里是一个完成的屏幕截图 文件我不得不截屏,因为里面充满了非常奇怪的角色。我也一样 结果,而不使用fopen以二进制模式打开它们。它似乎附加了我的文件 多次,其中一些只进行了一半,后来又进行了另一半 我哪里出错了 我不知道为什么它调整了这么多 /*Write

你好。根据一个C Primer Plus示例,我编写了一个程序,可以附加 将用户指定的文件复制到主文件。起初,我写它只是为了和你一起使用 文本文件,但后来我把它改为二进制模式。我用它附加了四个文件。我得到了一些非常奇怪的结果,我不知道为什么。这里是一个完成的屏幕截图 文件我不得不截屏,因为里面充满了非常奇怪的角色。我也一样 结果,而不使用fopen以二进制模式打开它们。它似乎附加了我的文件 多次,其中一些只进行了一半,后来又进行了另一半

我哪里出错了

我不知道为什么它调整了这么多

/*Write a program that indefinitely takes in files to append to a master
  file. If the file names are the same, don't do it. If there's an error,
  don't do it. Exit with a blank line. Use a custom buffer.*/ 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME 25
#define BUFSIZE 1024
int append(FILE *, FILE *); 

int main(){
    char src[MAX_NAME], mainfile[MAX_NAME]; 
    FILE *src_ptr, *mainfile_ptr; 
    int successes = 0; 

    puts("Enter name of main file"); 
    if(gets(mainfile) == NULL){
        fprintf(stderr, "Error, couldn't get filename\n"); 
        return 1; 
    }
    if((mainfile_ptr = fopen(mainfile, "ab")) == NULL){
        fprintf(stderr, "Error, couldn't open mainfile\n");
        return 1; 
    }

    do{
        puts("Enter a filename to be appended"); 
        if(gets(src) == NULL || src[0] == '\0' || strcmp(src, mainfile) == 0){
            if(src[0])
                puts("Error, couldn't get filename!"); 
            continue; 
        } 

        if((src_ptr =fopen(src, "rb")) == NULL){
            puts("Error, could not open file");
            continue; 
        }

        if(setvbuf(src_ptr, NULL, _IOFBF, BUFSIZE) != 0){
            puts("Couldn't create filebuffer!"); 
            continue; 
        }

        if(append(src_ptr, mainfile_ptr) != 0){
            fflush(src_ptr); 
            puts("Couldn't append!"); 
            continue; 
        }

        fclose(src_ptr); 
        ++successes; 
        printf("Successfully appended %s, %d files total\n", src, successes);

    }while(src[0] != '\0'); 

    fclose(mainfile_ptr); 
    printf("Successfully appended %d files, bye!\n", successes); 
    return 0; 
}


int append(FILE *src, FILE *mainfile){
    size_t bytes = 0; 
    static char buffer[BUFSIZE];
    while(bytes = (fread(buffer, sizeof(char), BUFSIZE, src)) > 0)
       fwrite(buffer, sizeof(char), BUFSIZE, mainfile);  

    if(ferror(src) || ferror(mainfile))
        return 1; 

    return 0; 
}
应该是

while(bytes = (fread(buffer, sizeof(char), BUFSIZE, src)) > 0)
    fwrite(buffer, sizeof(char), BUFSIZE, mainfile); 
在fread返回小于BUFSIZE字节的情况下,您正在将以前读取的数据写入main文件


您还可以检查fwrite是否返回字节,如果写入的缓冲区较少,则选择是中止还是重试写入缓冲区的其余部分。

gets将被取消。可能太过meta,但strcmp不是测试输入文件是否与输出文件相同的好方法。练习:你能说出一个或多个原因吗?请注意,你不应该使用gets函数,因为它本质上是不安全的。这个函数在C99中被弃用了,完全没有出现在C11中。我想你的意思是:while bytes=freadbuffer,sizeofchar,BUFSIZE,src>0,left before bytes=?哦,天哪,你说得对。当缓冲区未完全满时,我仍在写入BUFSIZE字节,而不是实际读取的字节数。@GrijeshChauhan谢谢,我错过了。现在我的回答又补充了一句。
while((bytes = fread(buffer, sizeof(char), BUFSIZE, src)) > 0)
    fwrite(buffer, sizeof(char), bytes, mainfile);