C语言 使用 scanf() 读取多行输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13592875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading multiple lines of input with scanf()
提问by user688604
Relevant code snippet:
相关代码片段:
char input [1024];
printf("Enter text. Press enter on blank line to exit.\n");
scanf("%[^\n]", input);
That will read the whole line up until the user hits [enter], preventing the user from entering a second line (if they wish).
这将读取整行,直到用户点击 [enter],防止用户输入第二行(如果他们愿意)。
To exit, they hit [enter] and then [enter] again. So I tried all sorts of while loops, for loops, and if statements around the scanf() involving the new line escape sequence but nothing seems to work.
要退出,他们按 [enter] 然后再按 [enter]。所以我尝试了各种 while 循环、for 循环和围绕 scanf() 的 if 语句,涉及新行转义序列,但似乎没有任何效果。
Any ideas?
有任何想法吗?
回答by tmyklebu
Try this:
尝试这个:
while (1 == scanf("%[^\n]%*c", input)) { /* process input */ }
回答by pablo1977
As was yet pointed out, fgets()is better here than scanf().
正如尚未指出的那样,fgets()这里比scanf().
You can read an entire line with fgets(input, 1024, stdin);
where stdinis the file associated to the standard input(keyboard).
The function fgets()reads every character from the keyboard up to the first new-line character: '\n' (obtained after pressing ENTERkey, of course...).
Important:The character '\n' will be part of the array input.
您可以阅读与标准输入(键盘)相关联的文件fgets(input, 1024, stdin);
在哪里的整行。
该函数读取键盘上的每个字符,直到第一个换行符:'\n'(当然是按ENTER键后获得的...)。重要提示:字符 '\n' 将是数组input 的一部分。 stdinfgets()
Now, your next step is to verify if all the characters in the array input,
from the first to the '\n', are blanks.
Besides, note that all the characters after the first '\n' in inputare garbage, so you have not to check them.
现在,您的下一步是验证数组input中的所有字符(
从第一个到“\n”)是否都是空白。
另外,注意输入中第一个'\n'之后的所有字符都是垃圾,所以你不必检查它们。
Your program could be as follows:
你的程序可能如下:
char input[1024];
printf("Enter text. Press enter on blank line to exit.\n");
while (1) {
if (fgets(input, 1024, stdin) == NULL)
printf("Input Error...\n");
else {
/* Here we suppose the fgets() has reached a '\n' character... */
for (char* s = input; (*s != '\n') && isspace(*s); s++)
; /* skipping blanks */
if (*s == '\n')
break; /* Blank line */
else
printf("%s\n", input); /* The input was not a blank line */
}
}
That code must be written inside your main()block and,
more importantly, it is necessary to include the header <ctype.h>before all,
because the isspace()function is used.
The code is simple: the while is executed for ever, the user enter a line in each iteration, the ifsentences checks if some error has happened.
If everything was fine, then a for(;;)statement is executed, which explores the array inputto watch if there are just blanks there... or not.
The foriterations continue up to the first new-line '\n' is found, or well, a non-blank character appears.
When forterminates, it means that the last analyzed character, which is held in *s, is a newline (meaning that all earlier characters were blanks), or not (meaning that at least there is some non-blank character in input[], so inputis a normal text).
该代码必须写在您的main()块中,
更重要的是,必须<ctype.h>在所有之前包含标头,
因为使用了该isspace()函数。
代码很简单:while永远执行,用户在每次迭代中输入一行,if语句检查是否发生了某些错误。
如果一切正常,则执行for(;;)语句,该语句探索数组输入以观察那里是否只有空白......
在对迭代持续到第一个新行“\ n”被发现,或者不好,一个非空白字符出现。
当为终止,这意味着保存在 中的最后一个分析的字符*s是换行符(意味着所有较早的字符都是空白),或者不是(意味着至少在input[] 中有一些非空白字符,所以input是普通文本)。
The "ethernal"
while(1)is broken only in case that a blank-line is read (see thebreakstatement in 11th line).
while(1)只有在读取空行的情况下,“ethernal”才会被破坏(请参阅break第 11 行中的声明)。
回答by chux - Reinstate Monica
OP says "To exit, they hit [enter] and then [enter] again"
OP 说“要退出,他们按 [enter] 然后再按 [enter]”
unsigned ConsecutiveEnterCount = 0;
for (;;) {
char buffer[1024];
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
break; // handle error or EOF
}
if (buffer[0] == '\n') {
ConsecutiveEnterCount++;
if (ConsecutiveEnterCount >= 2 /* or 1, not clear on OP intent */) {
break;
}
}
else ConsecutiveEnterCount = 0;
// Do stuff with buffer;
}
回答by Farhad Hossain
#include <stdio.h>
int main(){
char arr[40];
int i;
for( i = 0; i < sizeof(arr); i +=2 ){
scanf("%c%c",&arr[i],&arr[i+1]);
if( arr[i] == '\n' && arr[i+1] == '\n' )
break;
}
printf("%s", arr);
return 0;
}
回答by autistic
... I tried all sorts of while loops, for loops, and if statements around the scanf() involving the new line escape sequence but nothing seems to work.
...我尝试了各种 while 循环、for 循环和围绕 scanf() 的 if 语句,涉及新行转义序列,但似乎没有任何效果。
It seems you tried everything that you shouldn't have tried, prior to reading! A C programmer is expectedto read manualslest they want to run into undefined behaviourwhich causes headaches like the one you've experienced. To elaborate, you can't learn C by guessinglike you can Java.
在阅读之前,您似乎尝试了所有不应该尝试的东西!AC程序员预计到阅读说明书,以免他们要碰到不确定的行为引起头痛,就像你所经历的一个。详细地说,您不能像 Java 那样通过猜测来学习 C。
Consider this your lesson. Stop guessingand start reading(the fscanfmanual)!
将此视为您的课程。停止猜测并开始阅读(fscanf手册)!
According to that manual:
根据该手册:
[Matches a non-emptysequence of bytes from a set of expected bytes (the scanset).
[匹配一组预期字节(扫描集)中的非空字节序列。
The emphasis is mine. What you seem to be describing is an emptysequence of bytes, which means that the match fails. What does the manual say about matching failures?
重点是我的。您似乎在描述的是一个空的字节序列,这意味着match failed。手册对匹配失败有什么看法?
Upon successful completion, these functions shall return the number of successfully matchedand assigned input items; this number can be zero in the event of an early matching failure. If the input ends before the first conversion (if any) has completed, and without a matching failure having occurred, EOF shall be returned. If an error occurs before the first conversion (if any) has completed, and without a matching failure having occurred, EOF shall be returned...
成功完成后,这些函数将返回成功匹配和分配的输入项的数量;如果早期匹配失败,此数字可以为零。如果输入在第一次转换(如果有)完成之前结束,并且没有发生匹配失败,则应返回 EOF。如果在第一次转换(如果有)完成之前发生错误,并且没有发生匹配失败,则应返回 EOF...
Again, the emphasis is mine... This is telling you that like most other C-standard functions, you need to check the return value!For example, when you call fopenyou then write some idiom along the lines of if (fp == NULL) { /* handle error */ }.
同样,重点是我的......这告诉你,像大多数其他 C 标准函数一样,你需要检查返回值!例如,当你打电话给fopen你时,然后写一些类似if (fp == NULL) { /* handle error */ }.
Where's your error handling?Note that the return valueisn't merely a binary selection; where nconversions are performed, there are n+2possible return values in the range of: EOF, 0 .. n. You should understand what each of those means, beforeyou try to use fscanf.
你的错误处理在哪里?请注意,返回值不仅仅是一个二进制选择;在n执行转换的地方,n+2可能的返回值范围为:EOF, 0 .. n。你应该了解每种这些手段的,之前您尝试使用fscanf。
回答by user2068378
you can use following funtion when u wants to read input from next line.
当您想从下一行读取输入时,您可以使用以下功能。
scanf("%d \n",&a);
scanf("%d \n",&b);
scanf("%d ",&c);
in case you are providing input from command line it will take another inout after line change.
如果您从命令行提供输入,则在换行后将需要另一个 inout。

