首页 > 解决方案 > 尝试使用 fread 和 fwrite 复制文件时出现问题

问题描述

我一直在尝试使用freadand将 2 个二进制文件复制到另一个write。我已经阅读了几篇解释它们如何工作的文章,但我不明白我的错误是什么。

我试过将 char 切换fread到 an 上,int这样-1不会干扰该过程,但它似乎没有用。

我查找了一些链接以寻找答案:

为什么“while (!feof(file))”总是错的?
https://www.tutorialspoint.com/c_standard_library/c_function_fwrite.htm
https://www.tutorialspoint.com/c_standard_library/c_function_fread.htm
复制二进制文件
在 C 中将数据从一个文本文件复制到另一个

while (tempNum != EOF) {
    fread(tempNum, 1, 1, fptr);
    fwrite(tempNum, 1, 1, fp);
}

供您测试的示例:

#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
FILE *fptr;
FILE *fp;

int main(int argc, char** argv)
{
    int flag = 0;
    int exist = 0;
    char currentChar = 0;
    int tempNum = 0;
    fptr = 0;
    fp = fopen(*(argv + 3), "r");
    fptr = fopen(*(argv + 2), "r");
    char temp_array[10000] = { 0 };

    if (fptr == NULL)
    {
        printf("we cannot extract from nothing.");
        flag++;
    }
    else if (fp != NULL)
    {
        printf("This file already exists. If you would like to overwrite it enter 0. %s");
        scanf("%d", &flag);
    }

    if (!strcmp(*(argv + 1), "textCopy") && flag == 0)
    {
        fclose(fp);
        fclose(fptr);
        printf("A");
        fp = fopen(*(argv + 3), "w");
        fptr = fopen(*(argv + 2), "r");
        printf("%s , %s", *(argv + 2), *(argv + 3));

        while (currentChar != EOF)
        {
            printf("a");
            currentChar = fgetc(fptr);
            fputc(currentChar, fp);
        }

        fclose(fp);
        fclose(fptr);
    }
    else if (!strcmp(*(argv + 1), "binaryCopy") && flag == 0)
    {
        printf("A");
        fptr = fopen(*(argv + 2), "r");
        fp = fopen(*(argv + 3), "w");

        while (tempNum != EOF)
        {
            fread(tempNum, 1, 1, fptr);
            fwrite(tempNum, 1, 1, fp);
        }
    }

    getchar();
    getchar();
    return 0;
}

预期:获得 2 个相同的文件。

实际:我成功复制了文件的前 6 个字节(我使用了十六进制车间),但之后 Visual Studio 崩溃并说传递给函数的参数fread认为输入是致命的。

标签: c

解决方案


首先,我尝试最小化您的程序。我假设您要执行复制二进制数据的路径。为了简单起见,我删除了不相关的东西并使用硬编码的输入和输出文件。

(原代码有一些不相关的错误,这里没有提到。)

#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
FILE *fptr;
FILE *fp;
int main(int argc, char** argv)
{
    int tempNum = 0;
    char temp_array[10000] = { 0 };

    fptr = fopen("input.txt", "r");
    /* TODO: handle possible error */
    fp = fopen("output.txt", "w");
    /* TODO: handle possible error */

    /* FIXME: This is not the correct way to check for EOF. */
    while (tempNum != EOF)
    {
        /* FIXME: The first argument must be a buffer for reading the data. You should check the return code. */
        fread(tempNum, 1, 1, fptr);
        /* FIXME: The first argument must be a buffer containing the data. You should check the return code. */
        fwrite(tempNum, 1, 1, fp);
    }
    /* TODO: close files */
    return 0;
}

现在是一个修改后的版本,可以工作并处理一些错误。

#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>

FILE *fptr = NULL;
FILE *fp = NULL;
int main(int argc, char** argv)
{
    int tempNum = 0;
    char temp_array[10000] = { 0 };

    fptr = fopen("input.txt", "r");
    if(fptr == NULL) /* handle possible error */
    {
        perror("fopen(input.txt)");
        return 1;
    }
    fp = fopen("output.txt", "w");
    if(fp == NULL) /* handle possible error */
    {
        perror("fopen(output.txt)");
        fclose(fptr);
        return 1;
    }

    do
    {
        tempNum = fread(temp_array, 1, 1, fptr);
        if(tempNum > 0)
        {
            if(fwrite(temp_array, 1, tempNum, fp) != tempNum)
            {
                perror("fwrite");
                fclose(fptr);
                fclose(fp);
                return 1;
            }
        }
    }
    while(tempNum > 0);

    /* after fread() returned less than we expected, check for error */
    if(ferror(fptr))
    {
        perror("fread");
        fclose(fptr);
        fclose(fp);
        return 1;
    }

    /* When we reach this point we can assume the loop ended on EOF */
    fclose(fptr);
    fclose(fp);
    return 0;
}

推荐阅读