C 为什么编译后的代码在linux中的windows中创建损坏的文件工作正常

C 为什么编译后的代码在linux中的windows中创建损坏的文件工作正常,c,linux,windows,gcc,copy,C,Linux,Windows,Gcc,Copy,以下代码在windows下使用gcc-o copy.exe copy.c从MinGW-w64(i686-7.1.0-posix-dwarf-rt_v5-rev0)编译而成,用于复制文件时会创建垃圾文件;复制的字节太多或太少。在带有gcc的Linux下,它可以正常工作(源和目标具有相同的md5、文本文件和二进制文件,这无关紧要) #包括 int main(int argc,char*argv[]){ 文件*fp=fopen(argv[1],“rb”); 文件*fpo=fopen(argv[2],“

以下代码在windows下使用gcc-o copy.exe copy.c从MinGW-w64(i686-7.1.0-posix-dwarf-rt_v5-rev0)编译而成,用于复制文件时会创建垃圾文件;复制的字节太多或太少。在带有gcc的Linux下,它可以正常工作(源和目标具有相同的md5、文本文件和二进制文件,这无关紧要)

#包括
int main(int argc,char*argv[]){
文件*fp=fopen(argv[1],“rb”);
文件*fpo=fopen(argv[2],“w”);
整数大小=1000000;
字符缓冲区[大小];
字节大小;
而(0<(字节=fread(缓冲区,1,大小,fp)))
fwrite(缓冲区,1,字节,fpo);
fclose(fp);
fclose(fpo);
返回(0);
}

问题在于您读入二进制数据,但随后尝试将该数据以文本形式写入,如您选择的模式所示:

FILE *fp = fopen(argv[1], "rb");
FILE *fpo = fopen(argv[2], "w");
这将在Windows和其他可能的操作系统上引起问题,因为不同的标准库处理行尾的方式不同。Windows使用
\r\n
作为行尾,从文本文件读入时将转换为
\n
,而在Linux下,行尾为
\n
,无需转换为
\n
。在编写文本文件时,Windows会将
\n
转换为
\r\n
,而Linux的行尾不需要转换

将第二行更改为

FILE *fpo = fopen(argv[2], "wb");

应该可以解决您的问题。

问题在于您读入二进制数据,但随后您尝试将该数据写入文本,如您选择的方式所示:

FILE *fp = fopen(argv[1], "rb");
FILE *fpo = fopen(argv[2], "w");
这将在Windows和其他可能的操作系统上引起问题,因为不同的标准库处理行尾的方式不同。Windows使用
\r\n
作为行尾,从文本文件读入时将转换为
\n
,而在Linux下,行尾为
\n
,无需转换为
\n
。在编写文本文件时,Windows会将
\n
转换为
\r\n
,而Linux的行尾不需要转换

将第二行更改为

FILE *fpo = fopen(argv[2], "wb");

应该可以解决您的问题。

那么,为什么您使用二进制模式进行读取,而不是写入?在windows上,此模式确实不同于文本模式。(由于windows上的行尾是
\r\n
,因此在读取时会转换为单个
\n
,在以文本模式写入时会转换回
\r\n
)次要:如将
大小
设置为65536的二次幂,则性能会更好。那么,为什么使用二进制模式进行读取,而不进行写入?在windows上,此模式确实不同于文本模式。(由于windows上的行尾是
\r\n
,因此在读取时会转换为单个
\n
,在以文本模式写入时会转换回
\r\n
)次要:如将
大小
作为65536的二次幂,性能会更好。这确实解决了问题。如果文本模式在不同平台上的行为不同,为什么会有人使用文本模式来读/写文件?@Niels,因为它在不同平台上的行为不同。编写文本文件时,可以方便地使用正确的行尾,而不必关心代码运行的平台。@Niels当C程序编写
'\n'
时,在文本模式下,它将转换为底层操作系统的行尾表示。当C程序以文本模式读取时,操作系统的行尾也会进行类似的转换,程序会看到一个
'\n'
。如果你不想要这些翻译,那就是二进制模式的用途。这确实解决了这个问题。如果文本模式在不同平台上的行为不同,为什么会有人使用文本模式来读/写文件?@Niels,因为它在不同平台上的行为不同。编写文本文件时,可以方便地使用正确的行尾,而不必关心代码运行的平台。@Niels当C程序编写
'\n'
时,在文本模式下,它将转换为底层操作系统的行尾表示。当C程序以文本模式读取时,操作系统的行尾也会进行类似的转换,程序会看到一个
'\n'
。如果你不想要这些翻译,那就是二进制模式的用途。