我正在尝试使用 fread 和 fwrite 来制作复制功能,但根据缓冲区大小,我不断得到奇怪的输出

I am trying to use fread and fwrite to make a copy function but I keep getting strange output depending on the buffer size

我正在尝试编写一个复制函数,该函数在命令行中 运行 时接受三个参数。该程序 运行 使用程序名称,后跟用户指定的缓冲区大小,然后是输入文件的名称和输出文件的名称。

例如>>copyf 1024 input.txt output.txt分别存入argv[0]到argv[3]

当我 运行 缓冲区大小为 1024 的代码时,我得到如下内容:

This is the beginning of the test file and I want to see how far it makes it in to the file before cutting stuff off.ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ

当我 运行 缓冲区大小为 32 的代码时,我得到如下内容:

This is the beginning of the test file and I want to see how far it makes it in to the file before cutting stuff off.tting stuff

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>

int main(int argc, char*argv[])
{
    int end = 0;
    char buffer[65536];
    //Error checking
    if (argc != 4)
    {
        end = 1;
        printf("Error-Insufficient Arguments (%d/4)\n", argc);


    }
    FILE*fp, *outFile;
    fp = fopen(argv[2], "r");
    outFile = fopen(argv[3], "a");
    if (fp == NULL)
    {
        end = 1;
        printf("Error-Input file is fake\n");
    }

    //No errors. Proceed with copy code
    int size = atoi(argv[1]);
    printf("Buffer size is: %d Bytes\n\n",size);

    if (end == 0)
    {
        printf("No Errors Detected\n\n");
        while (!feof(fp))
        {

            fread(&buffer, size, 1, fp);

            fwrite(&buffer, size, 1, outFile);

            for (int i = 0; i < 65536; i++)
            {
                buffer[i] = NULL;
            }
        }

    }
    fclose(fp);
    fclose(outFile);

    clock_t endTime = clock();
    float endTimeSec = endTime;
    printf("Runtime = %f\n\n", endTimeSec / 1000);
    return 0;
}

任何关于我做错的建议都将不胜感激。我觉得问题的根源在于我对 fread 和 fwrite 在这种情况下的工作方式的理解。

  • 您不能假设 fread() 填充了缓冲区。
  • 除非您使用 1 的元素大小,否则 fread() 无法告诉您部分读取。
  • 您需要将实际读取计数输入 fwrite()
  • 你需要循环。

综合起来:

while ((count = fread(buffer, 1, sizeof buffer, fin)) > 0)
{
    fwrite(buffer, 1, count, fout);
}

之前或之后将缓冲区清零是浪费时间。

你的代码有几个问题。

  1. 你只做了很少的错误处理(而不是真正重要的地方)

  2. 您打开的文件是 reading/writing 文本数据而不是二进制数据,因此文件数据中的换行符(如果有)可能会转换为不同的格式。对于真实副本,您根本不希望数据发生变化。

  3. 您要求 fread() 读取 1 个大小为 size 字节的元素。如果输入文件大小不是 size 的偶数倍,最后一个元素将失败并被忽略。为了解决这个问题,您需要让 fread() 读取 size 个大小为 1 字节的元素。

  4. 您忽略了 fread() 的 return 值,它告诉您实际读取了多少字节。不要向输出文件写入超过该数量的字节。

尝试更像这样的东西:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>

int main(int argc, char*argv[])
{
    FILE *fp, *outFile;
    char buffer[65536];
    int bufSize, numRead;

    if (argc != 4)
    {
        printf("Error-Insufficient Arguments (%d/4)\n", argc);
        return 0;
    }

    bufSize = atoi(argv[1]);
    if ((bufSize < 1) || (bufSize > sizeof(buffer))
    {
        printf("Error-Invalid Buffer Size (%d)\n", bufSize);
        return 0;
    }

    fp = fopen(argv[2], "rb");
    if (fp == NULL)
    {
        printf("Error-Input file not opened\n");
        return 0;
    }

    outFile = fopen(argv[3], "wb");
    if (outFile == NULL)
    {
        printf("Error-Output file not created\n");
        fclose(fp);
        return 0;
    }

    //No errors. Proceed with copy code
    printf("Buffer size is: %d Bytes\n\n", bufSize);

    do
    {
        numRead = fread(buffer, 1, bufSize, fp);
        if (numRead < 1)
        {
            if ((ferror(fp) != 0) && (feof(fp) == 0))
                printf("Error-Reading from Input file\n");
            break;
        }

        if (fwrite(buffer, numRead, 1, outFile) != 1)
        {
            printf("Error-Writing to Output file\n");
            break;
        }
    }
    while (1);

    fclose(fp);
    fclose(outFile);

    clock_t endTime = clock();
    float endTimeSec = endTime;
    printf("Runtime = %f\n\n", endTimeSec / 1000);

    return 0;
}