Search code examples
cmingw-w64

Why my code doesn't work with my VS Code, and Code Blocks?


I wrote the following C program:

#include <stdio.h>

int main()
{
    char d;
    char e;
    printf("Babanin adini gir. \n");
    scanf("%s", &d);
    printf("Ananin adini gir. \n");
    scanf("%s", &e);
    printf("Senin adin %c ya da %c", d, e);
return 0;

}

It works perfectly fine in online C compiler but not in my VSCode or Codeblocks, it only says

Gimme a letter. 
s
Gimme another letter. 
a
Your letter is  or a

like that, it doesn't read the first letter or print it. Why is that?


Solution

  • When you say char d;, you tell the compiler to reserve exactly one byte of memory to hold one character.

    Then when you say char e;, you tell the compiler to reserve exactly one byte of memory to hold another character.

    Then you say scanf("%s", &d); which has the compiler read an entire string (including the string terminator) and try to store it in the one byte of memory reserved by char d;

    The character you type when you run the program takes one byte of space and the string terminator takes another one so now you are storing two bytes of data in a spot only big enough for one byte.

    And then you do it again for the second scanf call.

    So now you have accessed memory you didn't reserve - you could have written over something really important. It is undefined behaviour and ANYTHING can happen (including making the program look as if it is working)

    So, if you want to use char variables like you are now, the scanf("%s", &d); should be scanf(" %c", &d); and the other scanf call should be changed the same way.

    The reason the scanf format string needs to start with a space is to tell the scanf function that it should ignore whitespace (like the newline that is created by pressing the enter key). Without that space, the second scanf will store a newline as its character because that is the second character that was input.

    You might think that you could also change the variables to char d[2]; and char e[2]; so there is room to store the character and the string terminator. But this is a bad idea because, if the user enters more than one character before they press enter, you will still write past the end of the memory. So it has the exact same problem.

    Another thing you could do (as suggested in the comments) is to not use scanf at all for reading single characters. If your variable is char d; then you could use d = getchar(); and that would work well - but you still need to do something to handle the newline character that comes in as the second character. That's why I think scanf(" %c", &d); is a good, simple way to make it work.

    One other thing to note: you should always check the return value of the functions you call. If reading input doesn't work you should tell the user that the input is invalid and then not produce invalid output.