问题描述
我做了一个简单的脚本,将一个文件内容重写为另一个文件内容。 这是代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char filename[1024];
scanf("%s",&filename);
// printf("Filename: '%s'\n",filename);
int bytesToModify; scanf("%d",&bytesToModify);
FILE *fp;
fp = fopen(filename,"r");
fseek(fp,SEEK_END);
int fSize = ftell(fp);
fseek(fp,SEEK_SET);
printf("%d\n",fSize);
char *buf = malloc(fSize*sizeof(char));
for (int i = 0; i < fSize; i++) {
buf[i] = getc(fp);
}
fclose(fp);
FILE *fo;
fo = fopen("out_file.txt","w");
for (int i = 0; i < fSize; i++) {
fwrite(&buf[i],1,fo);
}
fclose(fo);
return 0;
}
即使在这样的小文件上,我也可以看到工件。西里尔语的sybmol'я'文件结尾。 如果我尝试重写可执行文件,则会得到以下信息:
99%的文件刚刚变成了这些符号。我的代码有什么问题?
我正在将CodeBlocks与GCC编译器10.1.0版一起使用。 我的操作系统是Windows 10。
感谢您的帮助。
解决方法
-
您没有以二进制模式打开文件:
"rb"
和"wb"
。因此,fgetc
会将所有\r\n
变成单个\n
。 -
对于每个行终止符,减少一个字符的读取。但是,您仍然尝试阅读,
fgetc
将返回EOF
(和fgetc
returns anint
,notchar
)。由于EOF
在Windows上的值为-1
,当写入转换为unsigned char
的文件时,这会导致Я
为您在记事本中使用的编码(很可能是{{3 }}。
此外,由于您使用的是fwrite
,因此您可以类似地使用fread
。而且无需阅读,一次只写一个字符 ,只需使用
char *buf = malloc(fSize);
int bytesRead = fread(buf,1,fSize,fp);
fclose(fp);
和
int bytesWritten = fwrite(buf,bytesRead,fo);