为什么当我按 ctrl + D 时,我的程序在结束之前打印一些东西?

Why does my program print something before it ends when I press ctrl + D?

提问人:osito_solito 提问时间:3/14/2021 更新时间:3/14/2021 访问量:448

问:

因此,我编写了一个简单的程序,将小数转换为二进制,只接受正整数。因此,像 -2 和 1.1 这样的数字将输出“对不起,这不是一个正整数。它无限地要求用户输入一个数字,直到用户按下 。但是,当我测试它时,它会打印出“对不起......”语句,然后结束程序。ctrl + D

这是我的代码:

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

void DecToBin(int userInput){
    int binary[32];
    int i = 0;
    while (userInput > 0) {
        binary[i] = userInput % 2;
        userInput /= 2;
        i++;
    }
    for (int j = i - 1; j >= 0; --j) {
        printf("%d", binary[j]);
    }
}

int main(void) {
    double userDec;
    int temp;

    printf("Starting the Decimal to Binary Converter!\n\n");

    while(!feof(stdin)) {
        printf("Please enter a positive whole number (or EOF to quit): ");
        scanf("%lf", &userDec);
        temp = (int)(userDec);
        if ((userDec > 0) && (temp / userDec == 1)) {
            printf("\n\t%.0lf (base-10) is equivalent to ", userDec);
            DecToBin(userDec);
            printf(" (base-2)!\n\n");
        }
        else {
            printf("\tSorry, that was not a positive whole number.\n");
        } 
    }
    printf("\n\tThank you for using the Decimal to Binary Generator.\n");
    printf("Goodbye!\n\n");
    return 0; 
}

(所有的制表符和换行符都是它应该的格式,所以不要注意这一点) 因此,根据我的理解,我的程序在我的 while 循环中读取为 else。那么,知道为什么会这样吗?ctrl + D

C while-loop eof feof 函数

评论

0赞 klutt 3/14/2021
如果您不想接受浮点数,那么为什么要扫描浮点数并将其转换为整数,而不仅仅是扫描整数呢?
0赞 klutt 3/14/2021
另外,您应该尝试生成一个最小的可重现示例。我很有信心,你不打电话也会有同样的行为?它不太可能导致这种情况。DecToBin
0赞 osito_solito 3/14/2021
@klutt 我的指示告诉我数字 11.0 应该有效,所以这就是原因。但我的问题是EOF的事情,我相信其他一切都很好。
2赞 WhozCraig 3/14/2021
盲目地假设成功无济于事。如果调用结果不是,那么按照该语句执行任何操作都是没有意义的(也许这应该影响您的循环控制)。scanf1
1赞 klutt 3/14/2021
对于下一个问题要考虑的另一件事是,如果您觉得应该写“所有制表符和换行符都是应该格式化的,所以不要注意这一点”,请记住,通常最好只编辑打印输出,这样就没有理由写该评论。但有趣的问题。不知何故,我能理解为什么会有这种困惑,尽管当你经验丰富时,这种感觉非常明显。很有意思。因为即使我知道事实并非如此,也知道为什么,但我希望 C-d 以这种方式工作。

答:

4赞 klutt 3/14/2021 #1

似乎你认为 C-d 会触发代码中的某种中断。就像关键字一样。事实并非如此。break

阅读这篇文章,看看当你按C-d时会发生什么:https://stackoverflow.com/a/21365313/6699433

这不会导致 C 代码中发生任何特殊情况。 根本不会读任何东西。语句之后,代码会像往常一样继续,所以代码会无条件地进入语句。scanfscanfif

这也是一件非常严重的事情,因为您将使用 uninitialized。 返回成功分配的数目,您应始终检查返回值。因此,在您的情况下,您需要以下内容:userDecscanf

if(scanf("%lf", &userDec) != 1) { /* Handle error */ }

因为 if 不返回 1,则未赋值。scanfuserDec

要实现您想要的,只需执行以下操作:

if(scanf("%lf", &userDec) != 1)
    break;