C中的复制文件功能

时间:2015-03-16 14:14:34

标签: c file stream copy fopen

我尝试使用此功能复制文件,但输出文件包含奇怪的字符。

int File_Copy (char FileSource [], char FileDestination [])
{
    int     result      =   -1;
    char    c [1];
    FILE    *stream_R   =   fopen (FileSource,      "r");
    FILE    *stream_W   =   fopen (FileDestination, "w");   //create and write to file

    while ((c [0] = (char) fgetc(stream_R)) != EOF)
    {
        fprintf (stream_W, c);
    }

    //close streams
    fclose  (stream_R);
    fclose  (stream_W);

    return result;
}

我不知道出了什么问题。请帮忙。

2 个答案:

答案 0 :(得分:6)

问题是c[1]不能用作字符串,因为它不能包含终止nul字节,所以它应该是

char c[2] = {0};

以及c[2]也应该是int,就像这样

int c[2] = {0};

因为fgetc()返回int所以您的代码可能会溢出c[0],但您还可以改进其他一些内容。

  1. 您不需要c作为数组,您可以像这样声明它。

    int c;
    

    然后使用fputc();代替fprintf()

  2. 您必须检查fopen()调用中没有一个失败,否则您的程序将因NULL指针取消引用而调用未定义的行为。

  3. 这是您自己程序的强大版本,其中包含您在问题中描述的问题

    /*   ** Function return value meaning
     * -1 cannot open source file 
     * -2 cannot open destination file
     * 0 Success
     */
    int File_Copy (char FileSource [], char FileDestination [])
    {
        int   c;
        FILE *stream_R;
        FILE *stream_W; 
    
        stream_R = fopen (FileSource, "r");
        if (stream_R == NULL)
            return -1;
        stream_W = fopen (FileDestination, "w");   //create and write to file
        if (stream_W == NULL)
         {
            fclose (stream_R);
            return -2;
         }    
        while ((c = fgetc(stream_R)) != EOF)
            fputc (c, stream_W);
        fclose (stream_R);
        fclose (stream_W);
    
        return 0;
    }
    

答案 1 :(得分:2)

您是否有任何理由试图一次复制一个字节的文件?那将是如此缓慢!虽然您的主要问题可能是您使用fprintf(),而printf()函数用于打印格式化字符串,而不是单个字符。

如果您只是将字节从一个文件推送到另一个文件,那么您应该使用fread和fwrite,如下所示:

int File_Copy(char FileSource[], char FileDestination[])
{
    char    c[4096]; // or any other constant you like
    FILE    *stream_R = fopen(FileSource, "r");
    FILE    *stream_W = fopen(FileDestination, "w");   //create and write to file

    while (!feof(stream_R)) {
        size_t bytes = fread(c, 1, sizeof(c), stream_R);
        if (bytes) {
            fwrite(c, 1, bytes, stream_W);
        }
    }

    //close streams
    fclose(stream_R);
    fclose(stream_W);

    return 0;
}