2017-08-04 87 views
0

我在Ubuntu中使用gcc-7在c中創建了一個程序。我有可執行文件sambleb.out文件。我想用c編程複製該文件。這是程序。無法通過c程序複製二進制文件

#include <stdio.h> 
int main() 
{ 
    FILE *fp; 
    fp = fopen("sampleb.out","rb"); 

    FILE *fpcp; 
    fpcp = fopen("cp-of-sampleb.out","wb"); 

    char forcp; 
    while (1) 
    { 
     forcp = fgetc(fp); 
     if(forcp == EOF) 
      break; 
     fputc(forcp, fpcp); 
    } 

    fclose(fp); 
    fclose(fpcp); 
} 

當我編譯程序並執行它時,我得到了段錯誤。

$ a.out && chmod a+x cp-of-sampleb.out 
$ ./cp-of-sampleb.out 
Segmentation fault 

這裏是CP-的-sample.out

$ cat cp-of-sampleb.out 
ELF>[email protected]@@@8 @@@@@@��[email protected]@@@,, `` ( 
((`(`��[email protected]@DDP�[email protected]@44Q�tdR�td``��/lib64/ld- 
linux-x86-64.so.2GNU GNUX�T3�O���t�R�b�Ss�F 
                $ 
libc.so.6printf__libc_start_main__gmon_start__GLIBC_2.2.5ui 
3�`` `H�H�% 
      H��t�CH�� 

和sampleb.out的內容

$ cat sampleb.out 
ELF>[email protected]@@@8 @@@@@@��[email protected]@@@,, `` ( 
((`(`��[email protected]@DDP�[email protected]@44Q�tdR�td``��/lib64/ld- 
linux-x86-64.so.2GNU GNUX�T3�O���t�R�b�Ss�F 
                $ 
libc.so.6printf__libc_start_main__gmon_start__GLIBC_2.2.5ui 
3�`` `H�H�% 
      H��t�CH���5 
          �% 
          @�% 
           h������% 

h������%� 
]�8`��D]�fD�8`UH��8`H��H��H��H��? 
H�H��t�H��tU�8`H=8`H��t�H��t 
               ]�8`��]�fD�=a 

uUH���~����O 

]�D��@f.�UH��]��UH�忸@�������]�f.�DAWAVA��AUATL�% UH�- 
SI��I��L)�H�H���g���H��t 
1��L��L��D��A��H��H9�u�H�[]A\A]A^A_Ðf.���H�H��how are you I am 
fine this singale line is printed by multiline 
printf;4�����0���P����0��������zRx 

�����*zRx 

�$h���0FJ 
U                       
�?;*3$"DW���A�C 
Dd`���eB�B�E �B(�H0�H8�[email protected](B BB�����@�@ 
�@` `���o�@@�@         �@ 
? 
`0�@� ���o`@���o���[email protected](`@@GCC: (Ubuntu 7.1.0- 
5ubuntu2~16.04) [email protected]@[email protected]�@�@@[email protected]`@ �@ 
�@ 
    �@ 
@[email protected]�@�@@[email protected]` `(`�``(`8`�� 
                 `@�@! 
�@78`F `[email protected]`������(@���(`(���`�(`(8`8�08)8h� P� 

(我沒有貼最後一行的原因,他們的內容到很多)。因此,我可以看到我的程序只處理了前7行。如果你告訴我什麼是錯誤的,這將會非常有幫助?我仍然是菜鳥。

+5

'焦炭forcp;'==>'INT forcp;'。函數'fgetc'返回'int',所以在二進制數據中你可以區分'-1'EOF的0xFF數據。 –

+2

'chmode'可能是'chmod'的拼寫錯誤。您不測試文件是否已成功打開;這總是*壞* - **非常糟糕*** *** –

+2

['fgetc'](http://en.cppreference.com/w/c/io/fgetc)函數返回一個int '。這對於'EOF'檢查很重要。 –

回答

3

首先,任何這樣的程序在繼續之前應檢查fopen()的結果。如果你不這樣做,你可能會使用從fopen()返回的NULL指針,以防出現故障並且程序將崩潰。

您的直接問題是您將返回值fgetc()指定爲charfgetc()返回int其中要麼對應於unsigned char的值是EOF,一個int常量,它是從任何有效的字符不同

當你比較EOFchar可能發生的事情是這樣的:你char可以簽署,所以在二進制文件中,你可以找到一個字節是-1與簽署char-1經常用作int(!)值EOF,所以即使fgetc()確實有而不是返回EOF,您的比較也會如此。

修復:將char forcp;替換爲int forcp;

這就是說,這是非常低效的複製文件字節字節。你最好在下面的例子中也添加了適當的錯誤檢查使用緩衝區和fread()/fwrite()複印,如:

#include <stdio.h> 

#define BUFFERSIZE 8192 // 8 kiB 

int main(int argc, char **argv) 
{ 
    if (argc != 3) 
    { 
     fprintf(stderr, "Usage: %s source dest\n", argv[0]); 
     return 1; 
    } 

    FILE *src = fopen(argv[1], "rb"); 
    if (!src) 
    { 
     fprintf(stderr, "Error opening %s for reading.\n", argv[1]); 
     return 1; 
    } 

    FILE *dst = fopen(argv[2], "wb"); 
    if (!dst) 
    { 
     fclose(src); 
     fprintf(stderr, "Error opening %s for writing.\n", argv[2]); 
     return 1; 
    } 

    char buf[BUFFERSIZE]; 
    int rc = 1; // <- failure 
    do 
    { 
     size_t nread = fread(buf, 1, BUFFERSIZE, src); 
     if (nread < BUFFERSIZE) 
     { 
      if (ferror(src)) 
      { 
       fprintf(stderr, "Error reading from %s.\n", argv[1]); 
       goto done; 
      } 
      if (!nread) break; 
     } 

     if (fwrite(buf, 1, nread, dst) < nread) 
     { 
      fprintf(stderr, "Error writing to %s.\n", argv[2]); 
      goto done; 
     } 
    } while (!feof(src)); 

    rc = 0; // <- success 

done: 
    fclose(dst); 
    fclose(src); 
    return rc; 
} 
+0

thanks.you幫了我很多。 – voldimot