Почему нельзя использовать getc(f)) != EOF для прямого сравнения?

Я новичок в языке C, и теперь застрял с таким вопросом: почему я получаю странный результат, если использую приведенное выше выражение для печати строки в файле?

Вот ситуация: у меня есть файл (data.txt) со следующим содержимым:

"Всем привет!!"

И вот мой код:

int main()
{
   FILE *ptr = fopen("data.txt", "r");

   if (ptr != NULL)
   {
      while (getc(ptr) != EOF)    //print all contents in data.txt
         printf("%c", getc(ptr));
   }
   else
      printf("Open file failed.");

   return 0;
}

Результат выполнения:

"эль вроэ!"

Если я сначала назначу getc(ptr) переменной и сделаю сравнение, все пойдет нормально.

В чем разница между этими двумя методами?


person Bcpp    schedule 13.03.2020    source источник
comment
Подсказка: эль вроэ! это каждый второй персонаж из Hello Everyone!!.   -  person Quentin    schedule 13.03.2020
comment
Подумайте о том, что делает getc(): он читает (или потребляет) символ из ввода. Если вы вызываете его дважды, как в своем цикле, он читает два символа.   -  person M Oehm    schedule 13.03.2020
comment
Действительно неуклюжий способ сделать это без сохранения в переменной: while (ungetc(getc(ptr),ptr) != EOF)   -  person R.. GitHub STOP HELPING ICE    schedule 13.03.2020
comment
Я понял !! Всем спасибо, ребята :DD   -  person Bcpp    schedule 13.03.2020
comment
Если бы getc() называли get_next_character() (что он и делает), было бы это более очевидным? То есть каждый раз, когда вы его вызываете, меняется следующий символ.   -  person Arkku    schedule 13.03.2020


Ответы (2)


Вы извлекаете первый символ в состоянии while, а затем извлекаете второй символ в printf. Таким образом, вы печатаете только каждый второй символ в цикле.

Если хотите, сделайте что-то вроде:

int c;

while ((c = getc(ptr)) != EOF) {
printf("%c", c);
}
person Dr. Andrey Belkin    schedule 13.03.2020
comment
char c; неверен и является классической ошибкой, из-за которой байт 0xff неправильно интерпретируется как EOF. Это должно быть int c; - person R.. GitHub STOP HELPING ICE; 13.03.2020

Вы можете, конечно, но вам нужно сохранить прочитанный символ. Если вы этого не сделаете, он будет потерян.

int main()
{
   FILE *ptr = fopen("data.txt", "r");

   if (ptr != NULL)
   {
      int c;
      while ((c = getc(ptr)) != EOF)    //print all contents in data.txt
         printf("%c", c);
   }
   else
      printf("Open file failed.");

   return 0;
}
person 0___________    schedule 13.03.2020