-1

我正在用 C++ 编写一个灵活的命令行(但时间不长!)菱形正方形生成器。我刚刚写完用户输入的一半。但是,在最后一个命令中,输入“slips”,getchar() 会自动输入一个换行符。我已采取预防措施以确保它不会溢出,即同时刷新标准输入和标准输出。问题仍然存在。这是我的代码:

#include <stdio.h>
#include <stdlib.h>

int main () {
    unsigned  long seed = 0, x = 0, y = 0, initial = 0, range = 0;
    int smooth = 0, fail = 1;
    char flagchar1 = 'n';
    printf("Welcome to my diamond-square generator! This isn't full-feature yet, so I'm just gonna have you input the variables one by one. ");
    do {
        printf("Please input the seed (this is a positive integer):\n");
        fail = scanf("%lu", &seed);
        while (fail == 0) {
            printf("Try again, smartass.\n");
            fail = scanf("%lu", &seed);
        }
        fail = 1;
        printf("Now input the x, or horizontal, size of your grid:\n");
        fail = scanf("%lu", &x);
        while (fail == 0) {
            printf("An integer. Not a string. An integer. You can do that, can't you?\n");
            fail = scanf("%lu", &x);
        }
        fail = 1;
        printf("Now input the y, or vertical, size of your grid:\n");
        fail = scanf("%lu", &y);
        while (fail == 0) {
            printf("What was that supposed to be? An integer, please.\n");
            fail = scanf("%lu", &y);
        }
        fail = 1;
        printf("Now input about how high you'd like the grid to be (this goes from a scale of 1 to 256):\n");
        fail = scanf("%lu", &initial);
        while (initial == 0 || initial > 256 || fail == 0) {
            printf("ahahahahaha how HIGH do you have to be just to HAVE that hieght........\n");
            fail = scanf("%lu", &initial);
        }
        fail = 1;
        printf("Now input the range of the heights on your grid (this must be equal to or less than 256):\n");
        scanf("%lu", &range);
        while (range >= 256 || fail == 0) {
            printf("What did I say about being equal to or less than 256? Give me something reasonable to work with here.\n");
            fail = scanf("%lu", &range);
        }
        fail = 1;
        printf("Just one more variable to go! Now, I need you to input the smoothness of your grid. Smaller numbers make spikier grids. You can make this negative, but beware!\n");
        fail = scanf("%d", &smooth);
        while (fail == 0) {
            printf("That... was not a number.\n");
            fail = scanf("%d", &smooth);
        }
        fail = 1;
        printf("\nOkay. Are these the values you want?\n   Seed:       %lu\n   Width:      %lu\n   Length:     %lu\n   Height:     %lu\n   Range:      %lu\n   Smoothness: %d\nDo you want to keep these? Type Y/n.\n", seed, x, y, initial, range, smooth);
        fflush(stdin);
        fflush(stdout);
        flagchar1 = getchar();
    } while (flagchar1 != 'y' && flagchar1 != 'Y' && flagchar1 != '\n');
}

&& flagchar1 != '\n'这是我的输出,程序已经结束(如果我删除from ,程序只会重复整个 do-while 循环while()):

    欢迎使用我的菱形生成器!这还不是全功能,所以我会让你一一输入变量。请输入种子(这是一个正整数):
    12345678
    现在输入网格的 x 或水平尺寸:
    40
    现在输入网格的 y 或垂直大小:
    30
    现在输入您希望网格的高度(范围从 1 到 256):
    1288
    ahahahahahaha你必须有多高才能拥有那个hieght........
    128
    现在输入网格上的高度范围(必须等于或小于 256):
    30
    还有一个变量要走!现在,我需要你输入网格的平滑度。较小的数字使网格更尖。您可以将其设为负数,但请注意!
    10

好的。这些是你想要的值吗?
  种子:12345678
  宽度:40
  长度:30
  身高:128
  范围:30
  平滑度:10
你想保留这些吗?键入 Y/n。

发生了什么,我该如何解决?

PS我知道我的输入验证基本上没用。对此的帮助也非常感谢。

4

5 回答 5

2

使循环的结尾看起来像这样:

    // Ignore remaining characters on current line.
    int ch;
    while( (ch = getchar()) != EOF && ch != '\n')
      ;
    // fetch first character on next line
    flagchar1 = getchar();
} while (flagchar1 != 'y' && flagchar1 != 'Y' && flagchar1 != '\n');

在您'\n'最后一次调用scanf.

您不得依赖fflush(stdin)任何特定行为。fflush对输入流调用的结果是未定义的。请参阅使用 fflush(stdin)

于 2012-03-05T19:48:52.803 回答
0

代码的行为与您告诉它的完全一样。如果用户输入“y”、“Y”或回车,while 循环中的这些条件之一将为假,这将导致它退出。

你想要的是:

while (flagchar1 == 'y' || flagchar1 == 'Y' || flagchar1 == '\n');

编辑:我还将删除 fflush(stdin) 并将 getchar() 替换为 fgets()。这将保证在不必使用 fflush 的情况下读取整行,这可能是问题所在。

于 2012-03-05T19:33:31.113 回答
0

我猜你在Linux上?这在 Windows 中的 VS 上运行良好。它提示,从键盘读取,如果检查包含有问题的正确“y”或“Y”。

我可能会建议您尝试将最后一个 scanf 更改为:

fail = scanf("%d ", &smooth);

您也可以尝试调用 fpurge() 而不是 fflush(),但这是非标准的,我认为格式字符串末尾的空格会得到您想要的。

尾随空格将要求 scanf 使用输入数据中的任何额外空格(包括换行符)。fflush() 可能不会做你想要的输入。

我怀疑您使用的任何系统确实将回车留在了流中,如果您将 flagchar1 打印为 int,您将得到 10?

于 2012-03-05T20:12:35.113 回答
0

建议:

  1. 使用 C++ 流。
  2. 在比较字符之前使用tolower或。toupper
  3. 使用std::string.

使用的 C 语言fgets, gets, fflush, strcmp,在这方面存在许多问题。C++ 语言已经解决了这些std::stream类中的许多问题。

由于您没有使用 C++ 功能,因此您应该将C++标记更改为C

于 2012-03-05T20:36:39.077 回答
-1

尝试

} while (flagchar1 != 'y' || flagchar1 != 'Y' || flagchar1 != '\n');

代替

} while (flagchar1 != 'y' && flagchar1 != 'Y' && flagchar1 != '\n');

于 2012-03-05T19:36:26.813 回答