【问题标题】:copy file function in CC中的复制文件功能
【发布时间】:2015-03-16 14:14:33
【问题描述】:

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

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

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

【问题讨论】:

  • fgetc() 返回一个 int 类型的值。将其转换为 char 会丢失信息。

标签: c file stream copy fopen


【解决方案1】:

您尝试一次复制一个字节的文件有什么原因吗?那会很慢!虽然您的主要问题可能是您使用了 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;
}

【讨论】:

  • 我不知道其他功能。您的方式似乎对文件大小(c []的大小)有限制。有没有办法修改它以消除约束?
  • 这个版本更快,因为它一次读取 4096 个字节。如果您想一次读取 1 个字节,请将 4096 更改为 1。还需要 I/O 错误处理,就像 iharob 的回答一样。
  • @CaTx 文件大小没有限制。代码在循环中一次复制 4096 个字节,直到复制完所有数据。这比一次复制一个字节要快一些,但会消耗更多的内存(但现在 4 KB 是多少?)
【解决方案2】:

问题是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 指针取消引用而调用未定义的行为。

这是您自己程序的强大版本,解决了您在问题中描述的问题

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

【讨论】:

  • 我最初将它作为 int 。但是, fprintf () 采用 constchar[] 类型,如 --> int fprintf (FILE *stream, const char formatString[], ...)。我得到了一个致命的运行时错误。我该怎么办?
  • @CaTx 但你不需要fprintf() 来写单个字符。
  • 我应该改用什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 2015-07-26
  • 2011-12-02
  • 2017-07-13
  • 2023-01-28
  • 2015-02-27
相关资源
最近更新 更多