0

In the below program I am trying to get char and strings from the user and want to print char,string terminated with white space and string terminated with new line in a single program.but only char and string terminated with white space only get printed..String terminated with new line is not get printed..So do you find any mistake i had made ? or any solution to the above problem ? Please reply..Thanks in advance..

#include <stdio.h>
#include <string.h>
int main() 
{
    char ch;
    char s[10];
    char str[20];
    scanf( "%c",&ch);
    printf("%c\n",ch);
    scanf("%s",&s);
    printf("%s\n",s);
    fgets(str,20,stdin); 
    printf("%s", str);
    return 0;
}
Thomas Jager
  • 4,836
  • 2
  • 16
  • 30

1 Answers1

0

scanf() actually parses input, reading it is just a side-effect of parsing. fgets() on the other hand is intended for reading.

The %s format specifier for scanf() means accept anything that isn't whitespace. This especially means that reading will stop at the first whitespace character, because it can't be parsed according to the format string (%s accepts non-whitespace and there's nothing following in the format string).

So, if you just enter a single word and hit the Enter key, this key generates a newline character (\n). This is a whitespace, your scanf() ignores it. fgets() is specified to read anything up to (and including) a newline. In your code, it immediately finds a newline, so that's all it reads.

Note this explanation is a guess based on your description of what you see. With different input, it could fail in a different way. Keep in mind your question should include the exact input you provide, the exact output you get and what you expected instead in order to avoid such guessing work.


Also note that scanf("%s", ...) is potentially undefined behavior and a security risk just as bad as gets(). If the input in your example code doesn't contain a whitespace in the first 10 characters, you will overflow your buffer. Never write code like this. The immediate solution is to always give field widths with scanf() format specifiers that parse to strings -- in your example scanf("%9s", ...). The better solution is not to use scanf() at all. ever. For more information, see also my beginners' guide away from scanf().


A simple solution for what you're trying to do without using scanf() could look like this:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
    char buf[1024];

    if (!fgets(buf, 1024, stdin)) return EXIT_FAILURE;
    char *c = buf;
    while (*c && isspace(*c)) ++c;
    if (*c) printf("%c\n", *c);

    if (!fgets(buf, 1024, stdin)) return EXIT_FAILURE;
    char *word = strtok(buf, " \t\n");
    puts(word);

    if (!fgets(buf, 1024, stdin)) return EXIT_FAILURE;
    puts(buf);

    return EXIT_SUCCESS;
}