2017-07-18 22 views
0

下面的代碼,使用gcc -o copy在windows下使用MinGW-w64(i686-7.1.0-posix-dwarf-rt_v5-rev0)編譯的gcc.exe .exe用於複製文件時,copy.c創建垃圾文件;無論是複製很多還是太少的字節。在Linux下用gcc它工作正常(源和目標具有相同的MD5,文本文件,二進制文件,無所謂)爲什麼編譯的代碼在windows中創建損壞的文件在linux中工作正常

#include <stdio.h> 
int main(int argc, char *argv[]) { 
    FILE *fp = fopen(argv[1], "rb"); 
    FILE *fpo = fopen(argv[2], "w"); 
    int SIZE = 1000000; 
    char buffer[SIZE]; 
    size_t bytes; 
    while (0 < (bytes = fread(buffer, 1, SIZE, fp))) 
     fwrite(buffer, 1, bytes, fpo); 
    fclose(fp); 
    fclose(fpo); 
    return(0); 
} 
+7

那麼,爲什麼你使用*二進制模式*來讀取,但不寫?在Windows中,這種模式的確與**文本模式不同。 (因爲窗口上的行尾是'\ r \ n',所以在*文本模式下寫入時,在讀取時翻譯爲單個'\ n'並且翻譯回爲'\ r \ n') –

+1

Minor:與更好的性能與'SIZE'一樣是65536的2次方。 – chux

回答

3

的問題是,您在二進制數據的讀取,但你嘗試寫數據輸出的文本,如模式所示的你選擇這樣做:

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"); 

應該解決您的問題。

+0

這確實解決了這個問題。如果任何人在不同平臺上的行爲不同,爲什麼會使用文本模式來讀取/寫入文件? – Niels

+3

@Niels _因爲它在不同平臺上的行爲不同。在編寫文本文件時,可以方便地使用正確的行結束而不必關心代碼運行的平臺。 – Ctx

+0

@Niels當一個C程序在文本模式下寫入一個''\ n''時,它將被轉換爲底層操作系統的行尾表示。當一個C程序讀入文本模式時,操作系統的行尾被類似地翻譯,並且程序看到一個單獨的「\ n」。如果你不想要這些翻譯,那就是二進制模式。 –

相關問題