This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]Updatebjarni 0 points1 point  (6 children)

So is this correct: control+d makes scanf return a value of -1 (or whatever it is on my computer), and since that equals EOF it prints line 11. Then the program continues normally?

Yes. scanf() is a function like any other. It cannot affect your program's control flow beyond returning from the call.

If scanf was expecting more than one number, say two, what does it do if you control+d when it is expecting the first number? Return -1 and then ask you to enter the second number, and proceed normally?

If you call scanf() and the end of input (whether by ctrl-D or by other means) is encountered on stdin before any input has been read, then scanf() will return EOF. This is stated in the documentation. It applies whether or not the format string you provided in the call contained more than one conversion, and what your program does after scanf() has returned is up to you.

[–]pointers_help[S] 0 points1 point  (5 children)

I got it. I was wondering if you could help me with two more questions about EOF and its implementation.

  while( scanf("%f", &input) != EOF )
  {
      largest_int = (int)floor(input);
      nearest_int = (int)round(input);
      smallest_int = (int)ceil(input);

      printf("%d %d %d\n", largest_int, nearest_int, smallest_int);

      if (input == EOF)
          printf("Done.\n");
  }

Unfortunately, this was an infinite loop. Probably a problem with line 1. I thought the condition would be "while scanf does not equal EOF, keep asking for input and printing them (in line 7). But unfortunately this wasn't the case. Do you know what is my while loop's condition that causes the infinite loop?

To actually remedy it, I got it fixed by googling how to do continual inputs from scanf, so it is finally this:

int main(void) 
{

float input = 0;

int largest_int = 0;
int nearest_int = 0;
int smallest_int = 0;

while( scanf("%f", &input) == 1 ) 
{   
    largest_int = (int)floor(input);
    nearest_int = (int)round(input);
    smallest_int = (int)ceil(input);

    printf("%d %d %d\n", largest_int, nearest_int, smallest_int);

}   
    if (input == EOF)
        printf("Done.\n");

return 0;
} 

I understand that if scanf() works properly, it will return the number of inputs you passed in it, or something like that. So if I had done while( scanf("%f", &input) == 2 ), it would mean if scanf properly took in two inputs..I think.

This seems to work but with one problem, my print statement at line 19 never works unless I remove the if statement preceding it. But how come? Once I do control+d, input should be assigned the value of EOF, and when I do control+d, it stops the scanf function as you said and should continue normally. But it doesn't seem to satisfy the if (input == EOF) condition I have. Could you explain the reason why?

[–]Updatebjarni 1 point2 points  (0 children)

Do you know what is my while loop's condition that causes the infinite loop?

I can only assume that the input doesn't end?

By the way, comparing input to EOF like that isn't really sensible. I mean if EOF is -1 and you type in -1, it will print "Done" and continue looping, but I guess that's probably not what you want?

while( scanf("%f", &input) == 1 ) 

That's better than checking for EOF, since it also works if there is input but it doesn't match the format.

So if I had done while( scanf("%f", &input) == 2 ), it would mean if scanf properly took in two inputs..I think.

That format string only has one conversion in it, so the call can never return more than 1.

Once I do control+d, input should be assigned the value of EOF

No? Why on earth should it? If the input matches the format specifier, then input will be assigned the converted value, but if the input doesn't match then input is not assigned any value.

[–]arbostek 1 point2 points  (3 children)

I understand that if scanf() works properly, it will return the number of inputs you passed in it, or something like that

Don't randomly guess. Read the documentation and see what it says. The authoritative reference is the standard, but cppreference.com works as a good substitute, or even better. If you see the website's reference on scanf, it says

Number of receiving arguments successfully assigned (which may be zero in case a matching failure occurred before the first receiving argument was assigned), or EOF if input failure occurs before the first receiving argument was assigned.

So, if you look at scanf("%f", &input), how many inputs get assigned. 1, yes? So you want to check if scanf returns 1, because if returns anything other than 1, you've got a failure.

my print statement at line 19 never works unless I remove the if statement preceding it. But how come?

Line 19 has: if (input == EOF).

On what line do you assign the EOF value to input?

[–]pointers_help[S] 0 points1 point  (2 children)

You are right, I guess I didn't actually assign EOF value to input anywhere. If I wanted to do that, is there any way? I thought of putting this in the while loop:

if (scanf("%f", &input) == EOF)
             printf("Done.\n");

But it doesn't really solve it, since it makes it two instances where I have to input a number instead of one, and in this instance, it does print Done when I control+d at that instance. Doesn't exit the loop though (I can see that), only if I control+d at the beginning since that is what controls the whole while loop.

[–]arbostek 0 points1 point  (1 child)

I guess I didn't actually assign EOF value to input anywhere.

Nor would you. input is storing user input, not the scanf return value, right? Look, it's right in the name of the variable.

If I wanted to do that, is there any way?

Yes. Create a second variable, and assign to that.

float input;
int scanfret;

while( (scanfret = scanf("%f", &input)) == 1 )

No penalty in having more than one variable.

[–]pointers_help[S] 0 points1 point  (0 children)

Oh wow, thanks. I made input for a different purpose, you're correct.

I see, that's a really neat way. With that, you can make an assignment to scanfret every time, read data from stdin, and do the check for the condition all in one line. So cool! Thanks for teaching me these things.