OP: первая часть "[^\n]"
означает принятие любого символа, кроме '\ n', для получения какого-либо символа, .... и сохранения его в str
.
* 1006. *
Не совсем.
Если первым прочитанным символом является '\n'
, сканирование прекращается. Ничего не сохраняется в str
, нулевой символ не добавляется, '\n'
остается в stdin
и функция возвращает 0 или EOF (я забыл, но это не 1)
Иначе не- '\n'
символы читаются и сохраняются до считывания '\n'
. '\n'
возвращается в stdin
, нулевой символ добавляется к str
. Сканирование продолжается в формате "\n"
. Если было прочитано 20 или более символов, результат будет неопределенное поведение .
Основная проблема
OP: Второй \ n соответствует совпадению \ n, которое завершает сканирование, в противном случае \ n освободит поток ввода и оставит для следующего действия ввода.
Нет. Формат "\n"
соответствует любому количеству пробелов, а не только 1 '\n'
. scanf()
потребляет пробелы, такие как '\n'
, ' '
, '\t'
, ..., до тех пор, пока не будет прочитан символ, не являющийся пробелом. Этот символ, не являющийся пробелом, затем возвращается в stdin
.
ОП: зачем мне вводить что-то еще и снова нажимать клавишу ввода, чтобы завершить sh сканирование?
Программа ожидает символ пробела, прежде чем он возвращается. Поскольку stdin
обычно строка в буфере, этот символ, не являющийся пробелом, не присваивается scanf()
до тех пор, пока у него не появится следующий '\n'
.
scanf("%[^\n]\n", str);
проблематично c. Используйте fgets()
. Проверьте возвращаемые значения.
char str[20];
if (fgets(str, sizeof str, stdin)) {
str[strcspn(str, "\n")] = '\0'; // lop off potential trailing \n if desired
printf(">>>>%s\n", str);
}
Если один, знак , должен использовать scanf()
, рассмотрите:
*str = 0; // Handle case when first letter is \n
scanf("%19[^\n]", str);// Consume up to 19 characters
scanf("%*1[\n]"); // Consume 1 \n if present-independent of success of previous