【问题标题】:Scanf not skipping when I press Enter当我按 Enter 时,Scanf 没有跳过
【发布时间】:2021-04-20 02:20:07
【问题描述】:

以下代码不断要求我给它 1 个输入,这意味着当我按“Enter”时,它不会跳到下一个 scanf,而是转到控制台上的下一行并等待输入。

int main()
{
    int i, print, line ;
    char oFile[50] , iFile[50] = "listsource.c" ;
    
    printf("Please enter the name of the input file: ") ;
    scanf("%s", iFile) ;
    
    printf("Please enter 0 to print to console, 1 to print to another file: ") ;
    scanf("%d", &print) ;
    
    printf("%s", iFile) ;
}

如果没有输入任何输入,我正在尝试给它一个默认值“listsource.c”,我已经尝试过 fgets 并且我遇到了同样的问题

【问题讨论】:

  • 所有“高级”转换,如 %d 或 %s 都对空格分隔的“单词”进行操作;换行符是一个空格,就 scanf 而言,就好像你按下了空格键。
  • 那么我该如何解决这个问题呢?
  • 读取字符 (%c) 或使用 fgets 读取行(可以为空,iirc)。另一方面,由于这无论如何都是某种初学者练习,只需强制用户进行“真实”输入并保持一切尽可能简单。
  • %c 只从字符串中读取 1 个字符,我需要它来读取完整的字符串
  • 使用 fgets 并检查是否有空行,其中只有 '\n'。如果它是空白的,那么使用你的默认值。

标签: c scanf enter skip


【解决方案1】:

试试这个:

#include <stdio.h>
int main()
{
    char hello[81];
    fgets(hello, 80, stdin);
    hello[strlen(hello) - 1 ] = '\0';
    // OR
    gets(hello);
}

它与在线 C 编译器一起工作。 尽管...gets() 将完成这项工作,但您将不得不删除换行符,但这是否危险,因为它会读取任意数量的字符,而不管您在声明它要进入的变量时指定的数量。因此它将覆盖编译器分配的内存。 (是的,这是 C 允许的。在 C 中,程序员应该知道自己在做什么,所以他得到了他想要的所有权力!)

【讨论】:

    【解决方案2】:

    所有scanf() 转换说明符 除了 "%c""%[..]""%n" 忽略前导空格'\n' 是空格。使用scanf(),您可以按Enter,直到您的手指使用"%d" 转换说明符脱落,并且永远不会被读取。 scanf() 将简单地丢弃所有空格并继续阻塞等待有效输入或EOF

    这只是scanf() 给新 C 程序员带来的众多陷阱中的一个。这就是为什么强烈建议您对所有用户输入使用fgets()。有了足够大小的缓冲区(字符数组),fgets() 将一次消耗一整行(包括尾随的'\n')。这大大简化了输入,因为在用户按下 Enter 后,stdin 中剩余的内容并不取决于是否发生了 scanf() matching-failure

    要从fgets() 填充的缓冲区末尾删除尾随'\n',只需使用strcspn(),如下所示:

        iFile[strcspn (iFile, "\n")] = 0;       /* trim \n from end of iFile */
    

    如果您确实需要转换缓冲区的内容,只需使用 sscanf() 提供缓冲区作为第一个参数,其余的就像使用 scanf() 一样——但在任何失败时,@ 中都没有留下任何内容987654342@,因为您已经完全阅读了fgets() 的用户输入。

    如果您尝试读取带有scanf()int,并且用户滑倒并点击'r' 到达'4',则会发生匹配失败并从@ 提取字符987654348@ 在stdin 未读 中停止离开'r'。如果你在一个循环中接受输入——你刚刚创建了一个无限循环......

    在您在这里要求用户输入01 的情况下,不需要从数字转换开始。只需使用fgets() 将输入读入缓冲区,然后检查缓冲区中的第一个字符是'0' 还是'1'(ASCII 数字)。无需转换。

    不要在代码中使用 MagicNumbers(例如 50)。如果你需要一个常量,#define 一个,或者使用一个全局的enum 来完成同样的事情,例如

    #define MAXFN  50       /* if you need a constant, #define one (or more) */
    #define MAXC 1024
    
    int main (void)
    {
        char buf[MAXC], /* oFile[MAXFN] ,*/ iFile[MAXFN];
    

    注意:如果在微控制器上编程,请相应减少读取缓冲区 (MAXC) 的最大字符数,否则,对于一般 PC,使用 1K 缓冲区即可)

    把它放在一起,并添加一个"print to another file - not implemented",来处理用户按要求输入1,你可以这样做:

    #include <stdio.h>
    #include <string.h>
    
    #define MAXFN  50       /* if you need a constant, #define one (or more) */
    #define MAXC 1024
    
    int main (void)
    {
        char buf[MAXC], /* oFile[MAXFN] ,*/ iFile[MAXFN];
        
        fputs ("Please enter the name of the input file: ", stdout);
        if (!fgets (iFile, MAXFN, stdin)) {     /* read ALL user input with fgets() */
            puts ("(user cancled input)");      /* validate, if manual EOF return  */
            return 0;
        }
        iFile[strcspn (iFile, "\n")] = 0;       /* trim \n from end of iFile */
        
        for (;;) {  /* loop continually until valid input from user or EOF */
            fputs ("\nPlease enter 0 to print to console, "
                    "1 to print to another file: ", stdout);
            if (!fgets (buf, MAXC, stdin)) {    /* read ALL user input with fgets() */
                puts ("(user cancled input)");  /* validate, if manual EOF return  */
                return 0;
            }
            if (*buf == '0') {      /* no need to covert to int, just check if ASCII '0' */
                puts (iFile);
                break;
            }
            else if (*buf == '1') { /* ditto -- just check if ASCII '1' */
                puts ("print to another file - not implemented");
                break;
            }
            fputs ("  error: invalid input, not 0 or 1\n", stderr);     /* handle error */
        }
    }
    

    (注意:当你需要用户提供特定的输入时,不断循环直到你得到你需要的,或者直到用户通过按 Ctrl + d 生成手动EOF (或 Ctrl + z 在 Windows 上))

    使用/输出示例

    故意为第一个输入单独按 Enter 并为接下来的两个输入提供无效输入,您将:

    $ ./bin/console_or_file
    Please enter the name of the input file: myInputFilename.txt
    
    Please enter 0 to print to console, 1 to print to another file:
      error: invalid input, not 0 or 1
    
    Please enter 0 to print to console, 1 to print to another file: bananas
      error: invalid input, not 0 or 1
    
    Please enter 0 to print to console, 1 to print to another file: 2
      error: invalid input, not 0 or 1
    
    Please enter 0 to print to console, 1 to print to another file: 0
    myInputFilename.txt
    

    检查一下,如果您还有其他问题,请告诉我。

    【讨论】:

      猜你喜欢
      • 2017-03-16
      • 2021-12-22
      • 2015-04-21
      • 1970-01-01
      • 2016-10-29
      • 1970-01-01
      • 2011-11-28
      相关资源
      最近更新 更多