Почему моя программа печатает что-то до завершения, когда я нажимаю 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 как else в моих циклах while. Итак, есть идеи, почему это так?


person osito_solito    schedule 13.03.2021    source источник
comment
Если вы не хотите принимать числа с плавающей запятой, то зачем сканировать число с плавающей запятой и преобразовывать его в целое число, а не просто сканировать целое число?   -  person klutt    schedule 14.03.2021
comment
Кроме того, вы должны попытаться создать минимально воспроизводимый пример. Я вполне уверен, что у вас было бы такое же поведение без вызова DecToBin? Очень маловероятно, что это вызывает это.   -  person klutt    schedule 14.03.2021
comment
@klutt Мои инструкции говорят мне, что числа 11.0 должны работать, вот почему. Но моя проблема связана с EOF, я считаю, что все остальное хорошо.   -  person osito_solito    schedule 14.03.2021
comment
И почему это не напечатать? Ожидаете ли вы, что он попадет в другую ветку в операторе if?   -  person klutt    schedule 14.03.2021
comment
@klutt Я думал, что когда он получит команду ctrl + D, он остановится и напечатает операторы вне цикла while?   -  person osito_solito    schedule 14.03.2021
comment
Слепое предположение, что scanf преуспеет, делу не поможет. Бессмысленно делать что-либо после этого утверждения, если результат вызова не равен 1 (и, возможно, это должно учитываться в вашем управлении циклом).   -  person WhozCraig    schedule 14.03.2021
comment
@osito_solito Обычно у меня нет мнения о том, какой ответ предпочитает принять пользователь, но ответ Омайра даже не решает вашу проблему. ;)   -  person klutt    schedule 14.03.2021
comment
Еще одна вещь, о которой следует подумать для вашего следующего вопроса, это то, что если вы чувствуете, что должны написать Все символы табуляции и новые строки именно так, как они должны быть отформатированы, поэтому не обращайте на это внимания, помните, что это обычно лучше просто отредактировать распечатки, чтобы вообще не было причин писать этот комментарий. Но интересный вопрос. Каким-то образом я могу понять, почему возникает эта путаница, хотя это очень очевидно, когда вы более опытны. Очень интересно. Потому что хоть я и знаю, что это не так и почему, но я хочу, чтобы C-d работал именно так.   -  person klutt    schedule 14.03.2021


Ответы (1)


Похоже, вы думаете, что C-d вызовет какой-то сбой в коде. Как ключевое слово break. Это неправда.

Прочитайте этот пост, чтобы узнать, что происходит, когда вы нажимаете C-d: https://stackoverflow.com/a/21365313/6699433

Это не приводит к тому, что в коде C происходит что-то особенное. scanf просто ничего не прочитает. После оператора scanf код будет продолжаться как обычно, поэтому код БУДЕТ безоговорочно входить в оператор if.

Это также довольно серьезная вещь, потому что вы будете использовать userDec неинициализированным. scanf возвращает количество успешных назначений, и вы всегда должны проверять возвращаемое значение. Итак, в вашем случае вы хотите это:

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

Потому что, если scanf не возвращает 1, userDec не назначено.

Чтобы добиться того, чего вы хотите, просто сделайте следующее:

if(scanf("%lf", &userDec) != 1)
    break;
person klutt    schedule 13.03.2021