2

Why does the code use

input_is_good = (scanf("%ld",&num) == 1);

instead of

input_is_good = scanf("%ld",&num);

Both of them are success, are there any difference between them?

#include <stdio.h>
#include <stdbool.h>

int main(int argc, const char * argv[]) {
    long  num;
    long sum =0L;
    bool input_is_good;
    
    printf("please enter an integer to be summed");
    printf("(q to quit):");
    input_is_good = (scanf("%ld",&num) == 1);
    while (input_is_good) {
        sum+= num;
        printf("please enter next integer (q to quit):");
        input_is_good = (scanf("%ld",&num) == 1);
    }
    printf("sum to %ld\n",sum);
    
    
    return 0;
}


What is the distinction between the former and the latter?

Oka
  • 23,367
  • 6
  • 42
  • 53
Jeff
  • 21
  • 2

2 Answers2

4

scanf returns the number of successful conversions that occur, not a boolean value indicating success.

%ld is one conversion specifier, so on success scanf returns 1.

If you were performing two conversions, as in scanf("%d %d", &a, &b), you would expect the function to return 2 if both conversions were successful.

On failure, scanf returns EOF or a short conversion count (e.g., scanf("%d %d", &a, &b) == 1 indicates a was converted but not b).

Simply writing

input_is_good = scanf("%ld",&num);

would cause

while (input_is_good) {

to proceed even when scanf fails and returns EOF, because EOF is a negative value (usually -1) which means it is truthy (not zero) and will be converted to the bool value of true.

On the other hand, the comparison of the return value against 1 creates a boolean result ((scanf("%ld",&num) == 1) will always be 0 or 1).

Oka
  • 23,367
  • 6
  • 42
  • 53
2
  • If you use input_is_good = scanf("%ld",&num);, input_is_good would be 1, 0 or EOF depending on the input. and they would break the while loop even if the user entered a valid long integer. For example, if the user entered 10, scanf would return 1 and input_is_good would be true. But if the user entered 20, scanf would return 0 because it already read the previous input and there is nothing left to read. This would make input_is_good false and break the while loop, even though the user entered a valid long integer.
  • If you use input_is_good = (scanf("%ld",&num) == 1);, If the user entered something else, such as a letter or a symbol, or reached the end of input, scanf will return 0 or EOF, which will make input_is_good false and break the while loop. If the user entered a valid long integer, scanf will return 1, which will make input_is_good true and continue the while loop. The code then adds the entered number to the sum variable and prompts the user for the next input.
Lee Dungx
  • 91
  • 4
  • 2
    Pedantically, `input_is_good` cannot be `EOF` due to its type (it will be 1, 0, or 1). – Oka Aug 02 '23 at 03:47
  • @Oka: I'm pretty sure stuff would break, but I never found a definite source for EOF must be -1 or if -2 would be ok by standard. – Joshua Aug 02 '23 at 04:16
  • 2
    @Joshua `EOF` expands to a negative `int` value; the redundancy in my comment was intentional as `(bool) EOF` will also be `1` (see C11 [§7.21.1](https://port70.net/~nsz/c/c11/n1570.html#7.21.1) and [§6.3.1.2](https://port70.net/~nsz/c/c11/n1570.html#6.3.1.2)). – Oka Aug 02 '23 at 04:26
  • @Oke: Well, I mean scanf will be 1, 0 or EOF, in this case this Input_is_good is assigned with scanf, I used wrong wording to denote it. thanks for feedback. – Lee Dungx Aug 02 '23 at 06:25