[英]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.