我正在尝试使用 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);
}
之前或之后将缓冲区清零是浪费时间。
你的代码有几个问题。
你只做了很少的错误处理(而不是真正重要的地方)
您打开的文件是 reading/writing 文本数据而不是二进制数据,因此文件数据中的换行符(如果有)可能会转换为不同的格式。对于真实副本,您根本不希望数据发生变化。
您要求 fread()
读取 1 个大小为 size
字节的元素。如果输入文件大小不是 size
的偶数倍,最后一个元素将失败并被忽略。为了解决这个问题,您需要让 fread()
读取 size
个大小为 1 字节的元素。
您忽略了 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;
}
我正在尝试编写一个复制函数,该函数在命令行中 运行 时接受三个参数。该程序 运行 使用程序名称,后跟用户指定的缓冲区大小,然后是输入文件的名称和输出文件的名称。
例如>>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);
}
之前或之后将缓冲区清零是浪费时间。
你的代码有几个问题。
你只做了很少的错误处理(而不是真正重要的地方)
您打开的文件是 reading/writing 文本数据而不是二进制数据,因此文件数据中的换行符(如果有)可能会转换为不同的格式。对于真实副本,您根本不希望数据发生变化。
您要求
fread()
读取 1 个大小为size
字节的元素。如果输入文件大小不是size
的偶数倍,最后一个元素将失败并被忽略。为了解决这个问题,您需要让fread()
读取size
个大小为 1 字节的元素。您忽略了
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;
}