-3

I'm required to do a seafood menu as an assignment in my college. I will provide the relevant code here:

 int main ()
{
int a,d;
float c ;
char b,s,S,m,M,l,L;

printf ("\n\t\t\t\tSeafood Menu\n");
printf ("----------------------------------------------------------------------------------\n");
printf ("\t\t\t\t\t\t      Dish Size\n");
printf ("Item Number\t Seafood Dish\t      Small\t       Medium      Large\t\n");
printf ("----------------------------------------------------------------------------------\n");
printf ("\t 1\t Fried   \t20.00 \t\t 40.00 \t\t 55.00\n");
    //Continue with a bunch of menu here

    printf ("   Enter item number            :");
    scanf ("%d",&a);
    printf ("   Enter dish size (S/M/L) :");
    scanf ("%s",&b);


        if ((a==1)&&((b=='s')||(b=='S')))
        {c=20.00;}
        //continue with a bunch of condition to choose the price per dish stated in the menu


    printf ("   Enter dish quantity     :");
    scanf ("%d",&d);
    printf ("   Price per dish size     :RM%.2f\n\n\n",c);


return 0;    
}

When I tried to change the format identifier in this to %c, it just stopped accepting input for that particular scanf.

printf ("Enter dish size (S/M/L):");
scanf ("%s",b);

I would like to attach images but it seems that I am not allowed to do so 'll leave two links:

Normal, using %s: and abnormal, using %c

I'm curious about why it doesn't work when I use %c while %s works? As all I enter there is just character. Please enlighten me.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Janson Liew
  • 11
  • 1
  • 2
  • 4
    Both variants invoke undefined behaviour. Please read the documentation of `scanf` and about the difference of a character and an _array of characters_, resp. a C string. – too honest for this site Mar 16 '17 at 16:47
  • The behavior of `%c` and `%s` should be clearly spelled out in your handy C reference manual. If you don't have a handy C reference manual, I recommend Harbison & Steele's [C: A Reference Manual](http://careferencemanual.com). `%c` reads a *single* character from the input stream and stores it to a single `char` object. `%s` reads a *sequence* of character values from the input stream until it sees whitespace or EOF and stores them to an *array* of `char` as a 0-terminated string. – John Bode Mar 16 '17 at 17:00

1 Answers1

1

I'm curious about why it doesn't work when I use %c while %s works?

Well, guess what, it did not work, even if it appeared to.

As mentioned in the man page, for scanf(), the type of arguments are

  • %c expects a pointer to char
  • %s expects a pointer to the initial element of an char array.

Quoting C11, chapter §7.21.6.2, (emphasis mine)

c Matches a sequence of characters of exactly the number specified by the field width (1 if no field width is present in the directive).

If no l length modifier is present, the corresponding argument shall be a pointer to the initial element of a character array large enough to accept the sequence. No null character is added.

s Matches a sequence of non-white-space characters.

If no l length modifier is present,the corresponding argument shall be a pointer to the initial element of a character array large enough to accept the sequence and a terminating null character, which will be added automatically.

In your case,

  • providing %s is wrong, as a single char is one element too short to scan and hold an array, that is null-terminated. This causes undefined behavior as memory overrun happens.

  • %c should have "worked" , if the input stream did not have the newline stored from previous ENTER key press. If you clean off the input stream of all pending inputs, you'll see it works. Use something like

    scanf(" %c", &b);   //the whitespace "eats up" all the previous whitespaces
    

    You can see this previous answer of mine, for details on the same.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 2
    "pointer to a `char` array" is misleading, as `%s` still expects a pointer to `char`, not a pointer to array of `char`. The man page on my system says, "pointer to the initial element of a character array" – Dmitri Mar 16 '17 at 16:59
  • @Dmitri Took my time to add the related quotes, hope this is no more misleading. Thanks. :) – Sourav Ghosh Mar 16 '17 at 17:20
  • @SouravGhosh Thank you for your explanation. This helped me to solve my problem. – Janson Liew Apr 07 '17 at 15:03