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

问题描述

所以我写了一个简单的程序,将十进制转换为二进制,只接受正整数。所以像 -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; 
}

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

解决方法

您似乎认为 C-d 会触发代码中的某种中断。就像关键字break。这不是真的。

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

这不会导致 C 代码中发生任何特殊情况。 scanf 不会读取任何内容。在 scanf 语句之后,代码将照常继续,因此代码将无条件地进入 if 语句。

这也是一件非常严重的事情,因为您将使用未初始化的 userDecscanf 返回成功赋值的次数,你应该经常检查返回值。所以在你的情况下你想要这个:

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

因为如果 scanf 不返回 1,则 userDec 未分配。

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

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