2

So I wrote a simple program that converts a decimal to binary, that only accepts positive whole numbers. So numbers like -2 and 1.1 would output "Sorry, that's not a positive whole number." It infinitely asks the user to input a number until the user presses ctrl + D. However when I tested it it prints out the "Sorry..." statement before it ends the program.

Here is my code:

#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; 
}

(All the tab and newlines are just how it's supposed to be formatted so don't pay attention to that) So from what I'm understanding, my program reads ctrl + D as the else in my while loops. So, any idea why that is?

  • If you don't want to accept floats, then why scan for a float and convert it to integer instead of just scanning for an integer? – klutt Mar 13 '21 at 21:05
  • Plus, you should try to produce a [mre]. I'm pretty confident that you would have the same behavior without calling `DecToBin`? It's very unlikely that it is causing this. – klutt Mar 13 '21 at 21:06
  • @klutt My instructions tell me to that numbers 11.0 should work, so that is why. But my problem is the EOF thing, I believe everything else is good. – osito_solito Mar 13 '21 at 21:06
  • And why would it not print that? Do you expect it to got to the other branch in the if statement? – klutt Mar 13 '21 at 21:11
  • @klutt I thought when it would get the command `ctrl + D` it would stop and print the statements outside the while loop? – osito_solito Mar 13 '21 at 21:14
  • 2
    Blindly assuming `scanf` succeeds isn't helping matters. It's pointless to do *anything* following that statement if the call result isn't `1` (and maybe that should factor into your loop control). – WhozCraig Mar 13 '21 at 21:19
  • @osito_solito Normally I don't have opinions on which answer a user chooses to accept, but Omairs answer does not even solve your problem at all. ;) – klutt Mar 13 '21 at 21:30
  • 1
    Another thing to think of for your next question is that if you feel that you should write *"All the tab and newlines are just how it's supposed to be formatted so don't pay attention to that"*, remember that it's usually better to just edit the printouts so that there's no reason to write that comment at all. But interesting question. Somehow I can understand why this confusion comes from, even though it's very obvious when you're more seasoned. Very interesting. Because even though I know it's not the case and why, but I **want** C-d to work that way. – klutt Mar 13 '21 at 21:40

1 Answers1

4

It seems like you think C-d would trigger some kind of break in the code. Like the keyword break. This is not true.

Read this post to see what's happening when you press C-d: https://stackoverflow.com/a/21365313/6699433

That does not cause anything special to happen in the C code. scanf will simply not read anything. After the scanf statement, the code will continue as usual, so the code WILL unconditionally enter the if statement.

This is also a pretty severe thing, because you'll be using userDec uninitialized. scanf returns the number of successful assignments, and you should always check the return value. So in your case you want this:

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

Because if scanf does not return 1, userDec is unassigned.

To achieve what you want, simply do this:

if(scanf("%lf", &userDec) != 1)
    break;
klutt
  • 30,332
  • 17
  • 55
  • 95
  • [Control-D does not send an end-of-file condition. It sends pending data immediately instead of waiting for enter/return: It terminates the current read operation, sending whatever data has been typed. If no data has been typed, the stream may interpret that as end-of-file.](https://stackoverflow.com/a/21365313/298225) – Eric Postpischil Mar 13 '21 at 21:37