【问题标题】:Read integers from standard input从标准输入读取整数
【发布时间】:2019-07-26 17:24:23
【问题描述】:

一个简单的C问题,我想从标准输入(用户输入)中读取整数,标准输入的每一行都包含一个整数,空行表示输入结束。 我尝试使用gets() 和scanf(),但它不起作用。

while (1){
            char a;
            scanf("%c",&a);
            printf("%c",a);
            if (a=='\r'||a=='\n'){
                break;
            }
        }

当我使用scanf()时,每次按回车时它都会终止;

while(1){
            char a[10];
            gets(a);
            if (a=='\r'||a=='\n'){
                break;
            }
        }

当我使用gets()时,'\r'或'\n'不能被读入缓冲区,所以它永远不会中断。

谁能帮帮我,提前谢谢!

【问题讨论】:

  • 永远不要使用gets。要使用 scanf 读取整数,请使用 %d
  • 混合scanfget/fgets 效果不佳。无论如何scanf 根本不是为交互式用户输入而设计的。请参阅下面的答案。

标签: c


【解决方案1】:

这是XY problem?吗?您可以使用fgetssscanf来完成这项工作。

#include <stdio.h>

int main(void) {
    char buffer[100];
    int number;
    while(fgets(buffer, sizeof buffer, stdin) != NULL) {
        if(sscanf(buffer, "%d", &number) != 1) {    // or strtol perhaps
            break;
        }
        printf("Number: %d\n", number);
    }
    return 0; 
}

【讨论】:

    【解决方案2】:

    我想从标准输入中读取整数

    在做

    while (1){
      char a;
      scanf("%c",&a);
      printf("%c",a);
      if (a=='\r'||a=='\n'){
        break;
      }
    }
    

    你读到一行包含任何字符,而不仅仅是数字表示

    在做

    while(1){
       char a[10];
       gets(a);
       if (a=='\r'||a=='\n'){
          break;
       }
    }
    

    achar*,所以在a=='\r'||a=='\n' 中你错误地将指针与字符进行比较,你想要*a=='\r'||*a=='\n'

    补充说明:

    • 从不使用gets,使用fgets读取一行,所以fgets(a, sizeof(a), stdin)
    • 但您仍会读取包含任何字符的行,而不仅仅是数字

    我想从标准输入(用户输入)中读取整数,标准输入的每一行都包含一个整数,空行表示输入结束。

    一个提案,行尾之前只包含空格和制表符的行被认为是空的,数字之前/之后的空格和制表符被绕过而不被认为是无效的:

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <ctype.h>
    
    int main()
    {
      while(1) {
        puts("enter number");
    
        char a[10];
    
        if (fgets(a, sizeof(a), stdin) == NULL) {
          puts("EOF");
          break;
        }
    
        errno = 0;
    
        char * endptr;
        long n = strtol(a, &endptr, 10);
    
        if (errno != 0) {
          puts("not a valid long");
        }
        else {
          /* check possible unexpected characters */
          char * p = endptr;
    
          for (;;) {
            if (*p == 0) {
              if (endptr == a) {
                puts("done");
                return 0;
              }
              printf("the number is %ld\n", n);
              break;
            }
            if (!isspace(*p++)) {
              puts("not (only) a valid long");
              break;
            }
          }
        }
      }
    }
    

    编译和执行:

    pi@raspberrypi:/tmp $ gcc -pedantic -Wextra n.c
    pi@raspberrypi:/tmp $ ./a.out
    enter number
    123
    the number is 123
    enter number
     123
    the number is 123
    enter number
    12a
    not (only) a valid long
    enter number
    a12
    not (only) a valid long
    enter number
    a
    not (only) a valid long
    enter number
    
    done
    

    【讨论】:

    • 你知道为什么if(a =='\r' || a == '\n') 'a' 会收到\n吗?
    • @raijin out of Windows the end if only by a \n,没有\r发送\读取,所以a =='\r'在Linux下永远不会是真的
    • 是的,在文本模式下,"\r\n"'\r' 被过滤掉了。
    • 不太明白。它不应该只接收a 变量的一个字符吗?我在 if 语句之前用 4 printf(%c, a) 测试了 OP 代码,它似乎与 \n 一起累积。输出为:bbbb\n\n\n
    • @raijin 当然,如果您谈到 OP 的第一个代码 a 仅包含一个字符,但该字符可以是 \r 或 \n (或其他)。没有积累,只有几个循环。这里不是提问/回答的最佳场所,要不要开一个新问题?
    【解决方案3】:

    我认为使用 getline 可能是更通用的解决方案,这里有一些示例代码,您可以根据自己的目的进行修改,“buf”将包含输入。

    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
        char *buf = NULL;
        int size;
        unsigned int length;
        size = getline(&buf, &length, stdin);
        if (size != -1)
            /* do anything you want with the stuff that was entered here */
            /* for the example I just write it back to stdout! */
            puts(buf);
        else
            /* this would be your "end" condition */
            printf("Nothing read!\n");
    
        printf("Size: %d\n Length: %d\n", size, length);
        free(buf);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-14
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 2013-03-30
      • 2012-02-17
      • 1970-01-01
      • 2015-07-05
      相关资源
      最近更新 更多