【问题标题】:C programming minor issue with interactive menu when input a floating value输入浮点值时交互式菜单的 C 编程小问题
【发布时间】:2014-02-02 06:49:18
【问题描述】:

我的程序可以很好地处理 char、超出范围的数字等无效输入,但是当输入 1.2 等浮点值时会出现问题。程序再次打印菜单,并在打印错误消息之前要求用户输入。我试图解决的是不再打印菜单,但仍然很挣扎。例如,

做出选择:1.1 [这里是菜单内容] 做出您的选择:该选择无效。请再试一次。

#include <stdio.h>

#define QUIT 0

int menu();

int main(void)
{
    int choice;
    char c;
    choice = menu();
    while(choice != QUIT)   //execute so long as choice is not equal to QUIT
    {
        choice = menu();
    }
}

int menu(void)
{
    int option;

    printf("Text Encoder Service\n\n");
    printf("1.\tEnter name of input file (currently 'Secret.txt')\n");
    printf("2.\tEnter name of output file (currently not set)\n");
    printf("3.\tEnter number of characters data should be shifted (currently +7)\n");
    printf("4.\tEncode the text\n\n");
    printf("0.\tQuit\n\n");
    printf("Make your selection: ");

    while( (scanf(" %d", &option) != 1) /* non-numeric input */
        || (option < 0)               /* number too small */
        || (option > 4))              /* number too large */
    {
        fflush(stdin);                    /* clear bad data from buffer */
        printf("That selection isn't valid. Please try again.\n\n");
        printf("Your choice? ");
    }
    return option;
}

【问题讨论】:

    标签: c


    【解决方案1】:

    我终于可以验证浮动输入了。非常感谢您的建议!这是我的新代码。您认为还有什么无效输入?

    int menu(void)
    {
        int option, parsed_inputs;
        char overcount_char;
        parsed_inputs = 1;
    
        printf("Text Encoder Service\n\n");
        printf("1.\tEnter name of input file (currently 'Secret.txt')\n");
        printf("2.\tEnter name of output file (currently not set)\n");
        printf("3.\tEnter number of characters data should be shifted (currently +7)\n");
        printf("4.\tEncode the text\n\n");
        printf("0.\tQuit\n\n");
        printf("Make your selection: ");
    
        parsed_inputs = scanf_s("%d%c", &option, &overcount_char);
        while( parsed_inputs > 1 )              /* number too large */
        {
            if((overcount_char != '\n') || (option < 0) || (option > 4))
            {
                fflush(stdin);                    /* clear bad data from buffer */
                printf("That selection isn't valid. Please try again.\n\n");
                printf("Your choice? ");
                scanf_s("%d%c", &option, &overcount_char);
            }
            else
                break;
        }
        return option;
    }
    

    【讨论】:

      【解决方案2】:

      1.1 的输入导致以下内容:

      • 字符串被读入内部缓冲区。
      • 然后与给定的格式字符串匹配。
      • 在第一次不匹配时,scanf() 调用将停止并返回成功扫描值的数量。

      让我们测试一下:

      #include <stdio.h>
      int main(int argc, char ** argv)
      {
          while (1) {
              int option;
              int n = scanf(" %d", &option);
              printf("%d %d\n", n, option);
              if (n <= 0) break;
          }
      }
      

      这个程序读取一行。

      假设我输入123 132

      然后会发生以下情况: * 由于格式字符串以空格开头,因此会消耗所有前导空格。在这种情况下,没有。 * 然后123被消费并放入option。 * 由于格式字符串现在结束,解析停止,n=1option=123。 * 在下一次循环运行中,同样的情况发生,给出n=1option=123

      但是:假设我输入123.321123#321

      然后会发生以下情况: * 由于格式字符串以空格开头,因此会消耗所有前导空格。在这种情况下,没有。 * 然后123 被消费并放入option。 * 由于格式字符串现在结束,解析停止,n=1option=123。 * 在下一个循环运行中,没有空格可以跳过。 .321 分别。 #321 尝试与 %d 匹配,但这些不是有效的整数。因此,我们得到n=0 并且option 保持其旧值。 * 由于没有从输入流中消耗任何字符(使用过的字符被再次放回),同样的事情会一遍又一遍地发生——这就是我输入if (n &lt;= 0) break;的原因。

      所以您看到该行为与浮点无关,因为我们使用.# 来“干扰”并不重要。

      我们将程序改为

      #include <stdio.h>
      int main(int argc, char ** argv)
      {
          while (1) {
              int option; char c;
              int n = scanf("%d%c", &option, &c);
              printf("%d %d %d %c\n", n, option, c, c);
              if (n <= 0) break;
          }
      }
      

      并运行它,输入4.235#6x7

      然后我们得到 * 第一次运行时n=2option=4c='.' * n=2, option=235c='#' 在第二次运行 * n=2option=6c='x' 在第 3 次运行 * n=2option=7c='\n'(换行符)在第三次运行

      并提示您进一步输入。

      这使您可以选择

      (parsed_inputs = scanf("%d%c", &option, &overcount_char)) < 1
      

      然后检查 overcount_char 包含的内容,只要 parsed_inputs 大于 1。

      【讨论】:

      • 我仍然无法通过您的提示解决问题。你能解释更多吗?
      • @user3077220 我试图通过修改答案来做到这一点。
      【解决方案3】:

      我认为您应该将 scanf() 放在 while 循环之前,并在 while 循环中明确检查“选项”变量。 发生的事情是,这里 scanf() 将始终返回值 1,因为 scanf() 返回 no。参数读取成功。因此,这个 while 循环将永远运行。欲了解更多信息,请查看此链接->http://www.cplusplus.com/reference/cstdio/scanf/

      希望这会有所帮助!

      【讨论】:

      • 为什么scanf() 总是返回1?如果我输入无效的内容,它当然会返回 0。
      • scanf() 将始终返回您尝试从中获取的输入数量..例如#include int main() { int i,j; printf("打印值的个数=%d\n", scanf("%d %d",&i,&j));返回0;这将返回 2,因为您从单个 scanf() 接受 2 个整数。如果在运行时 scanf() 无法从标准输入接受,或者如果您正在使用字符或浮点数,那么它应该返回 0、EOF 或一些随机错误。现在,在您的代码中,您实际上并没有检查 scanf() 的输入,而是检查 scanf() 返回的值。
      猜你喜欢
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      相关资源
      最近更新 更多