繁体   English   中英

使用 scanf() 读取多行输入

[英]Reading multiple lines of input with scanf()

相关代码片段:

char input [1024];

printf("Enter text. Press enter on blank line to exit.\n");
scanf("%[^\n]", input);

这将读取整行,直到用户点击 [enter],防止用户输入第二行(如果他们愿意)。

要退出,他们按 [enter],然后再次按 [enter]。 因此,我尝试了各种 while 循环、for 循环和涉及新行转义序列的 scanf() 周围的 if 语句,但似乎没有任何效果。

有任何想法吗?

尝试这个:

while (1 == scanf("%[^\n]%*c", input)) { /* process input */ }

正如尚未指出的那样, fgets()在这里比scanf()更好。

您可以使用fgets(input, 1024, stdin);读取整行
其中stdin是与标准输入(键盘)关联的文件。
函数fgets()从键盘读取每个字符,直到第一个换行符:'\n'(当然是在按ENTER键后获得的......)。
重要提示:字符 '\n' 将成为数组input的一部分。

现在,您的下一步是验证数组中的所有字符是否输入
从第一个到'\n',都是空白。
另外,请注意输入中第一个'\n'之后的所有字符都是垃圾,所以你不必检查它们。

你的程序可能如下:

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 */
   }
}

该代码必须写在您的main()块内,并且,
更重要的是,必须首先包含头文件<ctype.h>
因为使用了isspace()函数。
代码很简单:while永远执行,用户在每次迭代中输入一行, if语句检查是否发生了错误。
如果一切正常,则执行for(;;)语句,该语句探索数组输入以观察那里是否只有空白……或没有。
for迭代一直持续到找到第一个换行符 '\n',或者出现一个非空白字符。
for终止时,这意味着保存在*s中的最后一个分析字符是换行符(意味着所有早期字符都是空白),或者不是(意味着至少在input[]中有一些非空白字符,所以输入是普通文本)。

“ethernal” while(1)只有在读取空行的情况下才会被打破(参见第 11 行的break语句)。

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;
}
#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;    
}

...我尝试了各种 while 循环、for 循环和涉及新行转义序列的 scanf() 周围的 if 语句,但似乎没有任何效果。

阅读之前,您似乎尝试了所有不应该尝试的东西! AC 程序员应该阅读手册以免他们遇到未定义的行为,这会导致像您所经历的那样令人头疼的行为。 详细地说,你不能像学习 Java 一样通过猜测来学习 C。

把这当作你的教训。 停止猜测开始阅读fscanf手册)

根据该手册:

[匹配一组预期字节(扫描集)中的非空字节序列。

重点是我的。 您似乎在描述的是一个的字节序列,这意味着匹配失败 手册对匹配失败有什么说法?

成功完成后,这些函数将返回成功匹配和分配的输入项的数量 如果发生早期匹配失败,此数字可以为零 如果输入在第一次转换(如果有)完成之前结束,并且没有发生匹配失败,则应返回 EOF。 如果在第一次转换(如果有)完成之前发生错误,并且没有发生匹配失败,则应返回 EOF...

同样,重点是我的……这告诉您,与大多数其他 C 标准函数一样,您需要检查返回值 例如,当您调用fopen时,您会按照if (fp == NULL) { /* handle error */ }的行编写一些习语。

你的错误处理在哪里? 请注意,返回值不仅仅是二进制选择 在执行n次转换的情况下,有n+2可能的返回值,范围为: EOF , 0 .. n 在尝试使用fscanf之前,您应该了解每一个的含义。

当您想从下一行读取输入时,您可以使用以下函数。

scanf("%d \n",&a);
scanf("%d \n",&b);
scanf("%d ",&c);

如果您从命令行提供输入,则在换行后将接受另一个输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM