Разница в копировании EXE-файла и текстового файла в C - PullRequest
3 голосов
/ 06 октября 2011

Я написал следующий код для копирования текстового файла в другой:

     FILE *fpr, *fpw;
     int ch;
     fpr = fopen("M.txt","r");
     fpw = fopen("P.txt","w");
     if(fpr == NULL)
      printf("File open failed!");
     else
     {
       while(1)
        {
          ch = fgetc(fpr);
          if(ch == EOF)
             break;
          fputc(ch, fpw);
         }
       fclose(fpr);
       fclose(fpw);
       printf("Successfully copied!");
     }

Он работал отлично.Затем я изменил int ch на char ch, это также сработало для меня.Но когда я использовал следующий код для копирования файла .exe, копирование файлов работает некорректно.

     FILE *fpr, *fpw;
     char ch;
     fpr = fopen("M.exe","rb");
     fpw = fopen("P.exe","wb");
     if(fpr == NULL)
       printf("File open failed!");
     else
     {
       while(1)
        {
         ch = fgetc(fpr);
         if(ch == EOF)
           break;
         fputc(ch, fpw);
        }
      fclose(fpr);
      fclose(fpw);
      printf("Successfully copied!");
     }

Я изменил char ch на int ch, тогда он работает нормально!Почему это происходит с двоичными файлами, а не с текстовыми?Что происходит, когда char ch был использован в случае двоичного?Пожалуйста, помогите ... Спасибо за вашу обратную связь заранее.

Ответы [ 3 ]

6 голосов
/ 06 октября 2011

Это потому, что EOF, вероятно, 0 или 255 для символа, который может отображаться в середине двоичного файла, но не может отображаться в текстовом файле (вот почему для символа работает только текстовый файл).Однако EOF равно -1 для int, который не может отображаться в середине файла, несмотря ни на что (может только 0-255 включительно).

1 голос
/ 06 октября 2011

Поскольку fgetc() может возвращать целое число, соответствующее любому символу плюс отдельное значение EOF, вы не можете сохранить его результат в char и затем надежно проверить EOF. Вы должны использовать int, как вы делали изначально.

0 голосов
/ 06 октября 2011

fgetc() и fputc() предназначены для обработки текстовых данных, а не двоичных данных. Вместо этого используйте fread() и fwrite().

FILE *fpr, *fpw;
unsigned char b[1024];
bool ok = false;
fpr = fopen("M.exe","rb");
if (fpr == NULL)
    printf("File open M.exe failed!");
else
{
    fpw = fopen("P.exe","wb");
    if (fpw == NULL)
        printf("File open P.exe failed!");
    else
    {
        int read;
        while(1)
        {
            read = fread(b, 1, 1024, fpr);
            if (read < 1)
            {
                if (read == 0)
                  ok = true;
                break;
            }
            if (fwrite(b, read, 1, fpw) != 1)
                break;
        }
        fclose(fpw);
    }
    fclose(fpr);
}
if (ok)
    printf("Successfully copied!");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...