我正在尝试使用fread和fwrite来创建一个复制函数但是我一直在输出奇怪的输出,具体取决于缓冲区大小

时间:2016-02-05 23:02:52

标签: c++ copy buffer fwrite fread

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

E.g。 >> copyf 1024 input.txt output.txt,分别存储在argv [0]到argv [3]中。

当我运行缓冲区大小为1024的代码时,我会得到这样的结果:

  

这是测试文件的开头,我希望看到切割前多远使得它在该文件的东西off.ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ

当我运行缓冲区大小为32的代码时,我得到这样的结果:

  

这是测试文件的开头,我希望看到它在切割内容之前进入文件的距离有多远。

以下是代码:

#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在这种情况下如何工作的理解。

2 个答案:

答案 0 :(得分:2)

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

全部放在一起:

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

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

答案 1 :(得分:1)

您的代码存在一些问题。

  1. 您正在进行非常少的错误处理(而不是真正重要的地方)

  2. 您正在打开用于读取/写入文本数据而不是二进制数据的文件,因此文件数据中的换行符(如果有)可能会转换为其他格式。对于真正的副本,您根本不希望数据发生变化。

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

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

  5. 尝试更像这样的东西:

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