[英]How to read multiple lines of string from stdin in C?
我是 C 編程的新手。 假設我想從標准輸入讀取多行字符串。 我如何才能繼續閱讀直到僅包含 EOL 的行?
輸入示例
1+2\n
1+2+3\n
1+2+3+4\n
\n (stop at this line)
似乎當我直接按 enter(EOL) 時, scanf將不會執行,直到輸入 EOL 以外的其他內容。 我該如何解決這個問題?
如果有人可以幫助我,我將不勝感激。 謝謝你。
如果你想學習 C,你應該避免scanf
。 scanf
真正有意義的唯一用例是 C 是錯誤語言的問題。 花在學習 scanf 弱點上的時間並沒有得到很好的利用,而且它並沒有真正教給你很多關於 C 的知識。 對於這樣的事情,一次只讀一個字符,當你看到兩個連續的換行符時停止。 就像是:
#include <stdio.h>
int
main(void)
{
char buf[1024];
int c;
char *s = buf;
while( (c = fgetc(stdin)) != EOF && s < buf + sizeof buf - 1 ){
if( c == '\n' && s > buf && s[-1] == '\n' ){
ungetc(c, stdin);
break;
}
*s++ = c;
}
*s = '\0';
printf("string entered: %s", buf);
return 0;
}
從標准輸入讀取多行字符串。 我如何才能繼續閱讀直到僅包含 EOL 的行?
跟蹤讀取行首的時間。 如果在開頭讀取了'\n'
,則停止
getchar()
方法:
bool beginning = true;
int ch;
while ((ch = getchar()) != EOF) {
if (beginning) {
if (ch == '\n') break;
}
// Do what ever you want with `ch`
beginning = ch == '\n';
}
fgets()
方法 - 需要更多代碼來處理比 N 更長的行
#define N 1024
char buf[N+1];
while (fgets(buf, sizeof buf, stdin) && buf[0] != '\n') {
; // Do something with buf
}
如果您需要一次讀取一個字符,則可以使用getchar
或fgetc
,具體取決於您是從標准輸入還是其他stdin
讀取。
但是您說您正在閱讀字符串,所以我假設fgets
更合適。
主要有兩個考慮:
即使你是初學者——我不會把 go 放到這里的#2——你應該知道你可以防御它。 我至少會說,如果您在一個平台上編譯並從另一個平台的重定向文件中讀取標准輸入,那么您可能必須編寫防御。
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main (int argc, char *argv[]) {
char buf[32]; // relatively small buf makes testing easier
int lineContinuation = 0;
// If no characters are read, then fgets returns NULL.
while (fgets(buf, sizeof(buf), stdin) != NULL) {
int l = strlen(buf); // No newline in buf if line len + newline exceeds sizeof(buf)
if (buf[l-1] == '\n') {
if (l == 1 && !lineContinuation) {
break; // errno should indicate no error.
}
printf("send line ending (len=%d) to the parser\n", l);
lineContinuation = 0;
} else {
lineContinuation = 1;
printf("send line part (len=%d) to the parser\n", l);
}
}
printf("check errno (%d) if you must handle unexpected end of input use cases\n", errno);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.