Почему моя маленькая программа C печатает другую строку с помощью утилиты cat? - PullRequest
3 голосов
/ 04 августа 2020
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
  char a[6] = "abcdd";
  char b[5] = "1234";

  strcpy(a, b);

  write(1, a, 4);
  printf("AA\n");
  write(1, b, 4);
  printf("CC\n");
}

Я изучал strcpy fun c.

With ./a.out

1234AA
1234CC

With ./a.out | cat -e

12341234AA$
CC$

Я читаю кота человека. Не могу найти ничего с этим.

Какие изменения можно внести даже после компиляции?

Что случилось? Какая концепция мне не хватает?

1 Ответ

7 голосов
/ 04 августа 2020

Это проблема буферизации .

Вызовы write записывают непосредственно в дескриптор файла стандартного вывода. Эти записи небуферизованы .

Функция printf записывает в stdout, который в обычных случаях (когда stdout подключен к терминалу) буферизируется по строке (вывод фактически написано на новой строке).

Но когда stdout не подключен к терминалу, например, когда вы передаете вывод по конвейеру, тогда схема буферизации меняется. Он становится полностью буферизованным. Это означает, что буфер будет записан только при явном сбросе (или при заполнении буфера), что происходит при выходе из программы.

Следовательно, небуферизованный вывод из write будет записан первым. Затем при выходе из программы будет записан буфер stdout.

Если вы хотите одинакового поведения в обоих случаях, вы можете явно пропустить sh буфер stdout самостоятельно:

write(STDOUT_FILENO, a, 4);
printf("AA\n");
fflush(stdout);

[Обратите внимание, что я изменил "magi c number" 1 на предопределенный символ POSIX STDOUT_FILENO, который обычно легче понять, даже если быстро взглянуть на код .]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...