c - 如何让它注册 -1 作为退出并显示从 1 开始的编号列表?

标签 c arrays loops while-loop user-input

好的,提示是:

“编写一个简单的程序(演示数组的使用),要求用户输入数字并继续输入数字,直到用户输入-1或输入的数字总数达到20。您的程序将停止询问根据上述任一条件进行新输入。一旦满足上述条件之一,程序将输出所有输入的数字,如下所示:1. 888 2. 999 3. 4 …..等等。最后,程序需要显示输入的所有值的总和,不包括用于终止用户输入循环的 -1。该数组应该用于存储用户的输入,并在程序终止之前将它们显示出来。”

现在,我已经完成了大部分提示。它会在输入 20 个变量时停止并正确显示它们和总和。然而,无论我多么努力,我都无法让它注册-1作为退出。我也无法获得从 1. 开始到 20 结束的项目符号列表。其他一切都正常。

#include <stdio.h>
#define NUMBER_INPUTS 20 

int main(void){
    double userInput[NUMBER_INPUTS] = { 0 };
    int i = 0;

    while (i < NUMBER_INPUTS){
        printf("Enter number: \n", i);
        scanf("%lf", &userInput[i]);
        i++;        
    }

    for(i=0; i<NUMBER_INPUTS; i++)
        printf("%i. %.1lf \n", i, userInput[i]);    

    double total=0;
    for(i=0; i<NUMBER_INPUTS; i++)
        total+=userInput[i];
    printf("Total: %.1lf \n", total);

    return 0;
}

这是运行良好的代码。我在不同的地方尝试了不同的 do-while 来注册 -1,但它弄乱了输出列表并且不会停止运行。

#include <stdio.h>
#define NUMBER_INPUTS 20    

int main(void){
    double userInput[NUMBER_INPUTS] = { 0 };
    int i = 0;

do{
    while (i < NUMBER_INPUTS){
        printf("Enter number: \n", i);
        scanf("%lf", &userInput[i]);
        i++;        
    }
}while (userInput[i] != -1);

    for(i=0; i<NUMBER_INPUTS; i++)
        printf("%i. %.1lf \n", i, userInput[i]);    

    double total=0;
    for(i=0; i<NUMBER_INPUTS; i++)
        total+=userInput[i];
    printf("Total: %.1lf \n", total);

    return 0;
}

像这样吗?仅在输入的第 20 个变量处停止。如果我输入 -1 也没关系,它会继续下去。

对于我尝试使用的列表

i=i+1

将列表从 1. 获取到 20. 尝试将 i 变量增加 1,但由于某种原因,只是将输出列表缩短为仅显示 20. 以及总数?我不知道我做错了什么,希望得到一些意见。谢谢。

最佳答案

比较 float 与精确值时要非常小心。 (两个链接的点)。而double可以代表-1确切地说,不要养成相信 float 可以精确表示任何值的习惯——它们不能。请参阅:Is floating point math broken?Why Are Floating Point Numbers Inaccurate?

在输入-1时停止读取,您需要保留 i 的值具有有效 double 的(元素数量)当您离开读取循环时存储(即填充的数组元素数)。 int n = i;会起作用(或者只使用单独的计数器 n 并保存 i 用作循环变量)。然后在你的打印循环中。 for (i = 0; i < n; i++) 。正如您所看到的,您正在尝试打印 NUMBER_INPUTS每次。如果用户输入-1 3 个输入之后——这是行不通的。

为了正确使用任何输入功能,您必须验证返回。 (对于新的 C 程序员来说,scanf 尤其如此,其中包含许多陷阱)否则,在匹配失败时,您的数组元素将变得不确定,从 stdin 中提取字符。将停止将有问题的字符留在 stdin未读只是等待您下次尝试输入时再次咬住您。相反,验证、验证、验证。免得你们违反Commandment No. 6 。示例:

        if (scanf ("%lf", &userInput[n]) != 1) {    /* validate input */
            fputs ("error: invalid double input.\n", stderr);
            return 1;
        }

将其余部分放在一起,并给出一个在 +/- 1E-5 公差范围内检查浮点值的示例,您可以这样做:

#include <stdio.h>

#define NUMBER_INPUTS 20    

int main (void) {

    double userInput[NUMBER_INPUTS] = { 0 }, total = 0;
    int i = 0, n = 0;

    while (n < NUMBER_INPUTS){
        fputs ("Enter number: ", stdout);
        if (scanf ("%lf", &userInput[n]) != 1) {    /* validate input */
            fputs ("error: invalid double input.\n", stderr);
            return 1;
        }
        /* check for -1 (with +/- 1E-5 tolerance) */
        if (userInput[n] > -1.00001 && userInput[n] < -0.99998)
            break;
        total += userInput[n];
        n++;
    }

    putchar ('\n');
    for(i = 0; i < n; i++)
        printf("%d. %.1lf\n", i + 1, userInput[i]);    

    printf ("\nTotal: %.1lf \n", total);

    return 0;
}

示例使用/输出

$ ./bin/total
Enter number: 10
Enter number: 20
Enter number: 30
Enter number: 40
Enter number: 50
Enter number: -1

1. 10.0
2. 20.0
3. 30.0
4. 40.0
5. 50.0

Total: 150.0

仔细检查一下,如果您还有其他问题,请告诉我。你已经很接近了。

编辑 - 将输出元素指示更新为 i + 1满足您显示从 1 开始的编号列表的要求.

关于c - 如何让它注册 -1 作为退出并显示从 1 开始的编号列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59015014/

相关文章:

c - feof() 函数和 C 中文件的 EOF 有什么区别?

Java 8 : Reverse an int array in one line (using Streams API)

php循环问题

python - 将具有一个共同元素的列表列表组合在一起并保存到单独的文本文件中(python)

c - strcasecmp 实现不打印

c - 打印 union 的不同类型数组的输出

c - stat lib/ld-2.8.so 没有那个文件或目录

ios - 生成非重复随机数的 Swift 数组

javascript 数组值的总和

Perl:读取文件时跳过第 N 行