Вы можете использовать и игнорировать один символ новой строки с этим форматом преобразования: %*1[\n]
.Он потребляет не более одного символа новой строки и сбрасывает его.Обратите внимание, что если у вас есть несколько последовательных новых строк, будет пропущен только первый.Также обратите внимание, что fscanf()
будет читать дополнительный байт, чтобы проверить, совпадает он или нет.Этот байт будет возвращен в поток с ungetc()
, если он не совпадает.
Если вы использовали %*[\n]
, fscanf
будет продолжать читать поток, пока он не получит байт, отличный от новой строки или не достигнетконец файла, который может вызвать неожиданное поведение при обработке интерактивного ввода с терминала.
Ваш код fscanf(fp, "%s[\n]", buf);
вызывает неопределенное поведение, поскольку вы не предоставляете целевой массив для символов новой строки.Кроме того, у него есть еще один недостаток, поскольку вы не указываете максимальное количество байтов для хранения в buf
, что приводит к неопределенному поведению при вводе с длинными словами.
Попробуйте это:
char buf[100];
if (fscanf(" %99s%*1[\n]", buf) == 1) {
printf("read a word: |%s|\n", buf);
} else {
printf("no more words\n");
}
Если вы хотите включить новую строку в буфер, вам нужно будет сохранить ее в переменной и добавить вручную:
#include <stdio.h>
#include <string.h>
int main() {
for (;;) {
char buf[100];
char nl[2] = "";
int n = fscanf(stdin, " %98s%1[\n]", buf, nl);
if (n > 0) {
strcat(buf, nl);
printf("read a word: |%s|\n", buf);
} else {
printf("no more words\n");
break;
}
}
return 0;
}
Ввод:
Hello word
I am ready
Вывод:
read a word: |Hello|
read a word: |word
|
read a word: |I|
read a word: |am|
read a word: |ready|
no more words