1

scanf not working as expected with a normal input character

So I was just trying out the scanf() and a normal input/output of this function. I know that I had to leave a space before the input character and the operand% so my code is as below. Somehow I don't understand why whatever the input I inserted the output remains 0.

 #include<stdio.h>

 int main()
 {
  char c ;

  scanf(" %c",&c);
  printf("%c",c);

  return 0;
  }

I was expecting the output will be whatever the character I insert. For example, insert an "A" via keyboard and the output will be exactly an "A".


I'm using a vim environment to edit my code, but I found that if I run this code on codeblocks it works. What's the difference?

11
  • Works here Commented Sep 23, 2019 at 4:58
  • I declared only a char data type, how would I confirm the return value of scanf()? Commented Sep 23, 2019 at 5:12
  • I'm using a vim environment to edit my code, but I found that if I run this code on codeblocks it works. What's the difference? Commented Sep 23, 2019 at 5:16
  • 2
    It should work. The only thing is that you can make this change: scanf(" %c",&c);--> if (scanf(" %c",&c) != 1) printf("svanf error\n"; Commented Sep 23, 2019 at 5:16
  • 1
    It doesn't matter how you edit your code. How are you running it? Commented Sep 23, 2019 at 5:52

2 Answers 2

4

It appears you are not providing any non-whitespace (which are eaten away by th space in the format string, including newlines) characters (or perhaps nothing at all) from standard input. If this happens, scanf will fail to parse a char and leaves c uninitialized.

Using uninitialized variable is is Undefined Beheavior, so in theory anything could happen. In practice, from your description, it sounds like memory reserved for c happens to have byte value 0, which is unprintable character, so printf prints something else (maybe /0, maybe nothing). And then the environment (vim) might show you the program exit code, also 0 here (assuming the Undefined Behavior doesn' cause your program to crash).

To fix this, check return value of scanf:

 #include<stdio.h>

 int main()
 {
   char c ;

   int r = scanf(" %c",&c);
   if (r==1) {
      // Always print something and add newline
      // to be sure we see some output always.
      printf("c='%c'\n",c);
   } else {
      printf("scanf error: %d\n", r);
      // If r==-1, errno variable tells what error was
   }
   return 0;
 }

Practical hint: To provide standard input when there is no terminal (so you can't type the input), you can pipe something:

echo A | ./thisprogram
Sign up to request clarification or add additional context in comments.

7 Comments

Why do you suspect the program is being run from vim ??? This is the most strange thing I've read. Can you explain how/why do you suspect that?
@LuisColorado That is pretty much implied by OPs comment about how it doesn't work when editing in vim, but works when run under Code::Blocks.
The OP says he uses vim for editing the source file, not that he is running that example through vim. Anyway, filtering some part of the input file through the program or running it from :! will use stdin and stdout from/to the buffer, or the terminal, so he will have standard input and output anyway. In unix, it's almost impossible to run a program without stdin or stdout, despite being able to see them can be difficult sometimes.
@LuisColorado Mm, yeah (now that I tested :! myself). Having stdin be empty (or whitespace-only eaten away by the space in question code scanf format string would produce the same effect) is easy though. It would be necessary to know just how OP is running the code in the vim scenario.
Yeah, the OP doesn't check for input errors, but that's not the issue. The OP describes perfectly the input he had tested (single A followed by <kbd>Enter</kbd>) and that input must work with the program he posts.
|
1

I've tried to run your program (exactly as it appears in your question)

pru.c

 #include<stdio.h>

 int main()
 {
  char c ;

  scanf(" %c",&c);
  printf("%c",c);

  return 0;
  }

and with the input you posted in your question (just A plus Enter) and got the following result:

$ cc pru.c
$ ./a.out
A
A$ _

which is exactly the expected output. So the problem must be in another place, or you have a completely different scenario and need to provide more information.

I tested this on a PC (Intel Core Duo) with FreeBSD 12.0/CLANG compiler. (here $ is the unix prompt and _ is the cursor after the run) And of course, the program has been edited with vi(1) (this has no impact on the result).

Edit

Try to change

  printf("%c",c);

by this

  printf("0x%02x, [%c]\n",c,c);

so, you'll get an hex dump of the character just input, and also its representation as printed. The \n at the end is to ensure your shell prompt is not eating (overwriting) the last line output of your program (mostly if you have changed the prompt variable PS1) hidding the printed char.

That should produce (on your posted input) the following output:

$ cc pru.c                <--- compilation of new pru.c
$ ./a.out                 <--- default name for your program executable.
A                         <--- this is your input (followed by <return>)
0x41, [A]                 <--- this should be your program output.
$ _                       <--- prompt (and cursor) after your program execution

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.