0

Why the following code is getting terminated after one round if the getchar() in the 5th line is not used?

char s;
while(1){
    printf("Enter two integers: ");
    scanf("%d%d",&a,&b);
    getchar();
    c = a + b;
    printf("Addition of %d & %d is %d\n",a,b,c);
    printf("Add more numbers(yes/no): ");
    scanf("%c",&s);
    if(s == 'y')
        continue;
    else
        break;
}

And why using string is not working in the following code? I have included the <string.h> file.

char s[10];
while(1){
    printf("Enter two integers: ");
    scanf("%d%d",&a,&b);
    getchar();
    c = a + b;
    printf("Addition of %d & %d is %d\n",a,b,c);
    printf("Add more numbers(yes/no): ");
    scanf("%s",s);
    if(s == "yes")
        continue;
    else
        break;
}
Imtiaz
  • 25
  • 2
  • 7
  • `s == "yes"` You are telling the compiler to compare only `y` (the first character the array points to) with `yes` string literal, that mismatches. You need to use `strcmp()`. – Rohan Bari Feb 27 '21 at 11:10
  • 2
    @RohanBari That is not, what happens here. There is no `y` involved in the comparison. This comparison takes the address of array `s` and compares with the address of string literal `"yes"` which can never be true. – Gerhardh Feb 27 '21 at 11:13
  • Try (in the 1st version) `if (s == 'y') { continue; } else { printf("s is %d\n", s); break; }` – pmg Feb 27 '21 at 11:13
  • 1
    Don't ask multiple questions. Focus on one. – klutt Feb 27 '21 at 11:17
  • Using 'if (strcmp (s,"yes") ==0)' works in case of string. Thanks. @Rohan Bari – Imtiaz Feb 27 '21 at 11:18
  • Ok. Noted. @klutt – Imtiaz Feb 27 '21 at 11:19
  • Can you explain more about your comment? @Gerhardh – Imtiaz Feb 27 '21 at 11:22
  • Not working. @pmg – Imtiaz Feb 27 '21 at 11:25
  • It's not supposed to "work", @MukaddasImtiazHimel... it's supposed to give you a bit of information (the value of `s`) to help you make it "work". – pmg Feb 27 '21 at 11:31
  • Understood. @pmg – Imtiaz Feb 27 '21 at 11:33
  • 1
    If you only use the variable `s`, you are not referencing the first character in that array but he array itself. It decays to a pointer to first element. But as you do not have a `*` in front of it, you don't derefernce it. Therefore `s` means the address (probably on the stack) where `s` is located. Left side is a pointer. On the right side similar thing happens. `"yes"` is a string literal and decays to pointer to first character. But again, you don't dereference it. In the end you compare 2 pointers which cannot point to the same address. – Gerhardh Feb 27 '21 at 11:33
  • See: [scanf() leaves the new line char in the buffer](https://stackoverflow.com/q/5240789/6372809). As an aside, my opinion is that Carth... scanf should be deleted. – ilkkachu Feb 27 '21 at 13:08

1 Answers1

1

When you enter the input for the first scanf("%d%d",&a,&b) then you probably ended that with the Enter key.

That Enter key is added as a newline into the input buffer that scanf reads from.

If you don't have the getchar() call then that newline is what the next scanf("%c",&s) will read.

One solution is, as you've noted, to use getchar() to read and throw away the newline. Another solution is to ask scanf to do the same:

scanf(" %c",&s);
//     ^
// Note the space here!

The leading space tells scanf to skip and ignore all leading white-space character, of which newline is one such character.

Note that most format specifiers for scanf automatically skip and ignore leading white-space. For example %s will do that, which means your second version with scanf("%s",s) doesn't need the getchar() call.

Also note that this should have been easily deduced by spending five minutes in a debugger to step through the code statement by statement while monitoring variables and their values.


Then for s == "yes". What happens here is that the array s will decay to a pointer to its first element, as will the literal string, and then you compare these pointers to see if they are the same, which they will most likely never be.

It's somewhat simplified equivalent to this:

char yes_literal[4] = "yes";
if (&s[0] == &yes_literal[0]) ...
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621