2017-08-04 69 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