ANSI C - как читать из stdin слово за словом?

Код:

#include <stdio.h>
int main(void) { char i[50]; while(scanf("%s ", i)){ printf("You've written: %s \n", i); } printf("you have finished writing\n"); return 0;
}
</stdio.h>

Одна из проблем заключается в том, что код не работает так, как ожидается. Если я набрал:

abc def ghi.

Он выводит:

You've written: abc
You've written: def

Как я могу это исправить? Цель состоит в том, чтобы прочитать каждое слово из stdin, пока оно не достигнет "ENTER" или "." (Точка).

4 ответа

@cnicutar довольно близко, но вы, видимо, хотите только начать читать что-то, кроме белого, и хотите прекратить чтение одного слова, когда вы попадаете в пробел, поэтому для вас, сканирование, вы, вероятно, хотите что-то большее

while(scanf(" %49[^ \t.\n]%*c", i)) {

В этом начальное пространство пропускается по любому ведущему пробелу. Затем сканирующий набор считывает данные до тех пор, пока не получит пробел, вкладку, новую строку или период. Затем% * c считывает (но удаляет) следующий символ (обычно тот, который остановил сканирование).

Это может, однако, выбросить символ, когда/если вы достигнете конца буфера, так что вы можете использовать% c и снабдить вместо него символ, который нужно читать. Это позволит вам восстанавливаться с одного слова дольше, чем указанный вами буфер.


Как насчет:

scanf("%49[ ^\n.]", str)

Или что-то в этом роде.


Отключить scanf в целом и перейти с fgets:

while (fgets(i, sizeof i, stdin))
{ printf("you've written: %s\n", i);
}

со следующими оговорками:

  • Если в целевом буфере есть место, fgets будет хранить конечную новую строку как часть ввода;

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

int foundDot = 0; while (fgets(i, sizeof i, stdin) && !foundDot) { char *dot = strchr(i, '.'); char *newline = strchr(i, '\n'); if (dot != NULL) { foundDot = 1; *dot = 0; // overwrite the '.' character with the 0 terminator } if (newline != NULL) { *newline = 0; // overwrite newline character with 0 terminator } /** * Assuming you don't want to print a blank line if you find a dot * all by itself. */ if (strlen(i) > 0) printf("you've written: %s\n", i); }


Самый простой способ сделать это - flex. В противном случае вы повторяете сложную сложную работу и, вероятно, ошибаетесь.

Кроме того, прочитайте lex и yacc, 2nd edition.

licensed under cc by-sa 3.0 with attribution.