%c与%s的实际差异

时间:2017-03-16 16:46:01

标签: c arrays char scanf format-specifiers

我需要在我的大学里做一份海鲜菜单。我将在此提供相关代码:

 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;    
}

当我尝试将此格式标识符更改为%c时,它只是停止接受该特定scanf的输入。

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

我想附上图片,但似乎我不允许这样做会留下两个链接:

Normal, using %s:abnormal, using %c

我很好奇为什么在%c工作时使用%s时它不起作用?因为我进入的只有个性。请赐教。

1 个答案:

答案 0 :(得分:1)

  

我很好奇为什么当%s使用%c时它不起作用?

嗯,猜猜是什么,它没有用,即使它似乎。

如手册页中所述,对于scanf(),参数类型为

  • %c需要指向char
  • 的指针
  • %s需要一个指向char数组的初始元素的指针。

引用C11,章节§7.21.6.2,(强调我的

  

c匹配字段指定的字符序列   width (如果指令中没有字段宽度,则为1)

     

如果不存在l长度修饰符,则相应的参数应为a   指向大小足以接受的字符数组的初始元素的指针   序列。没有添加空字符。

     

s匹配一系列非空白字符。

     

如果不存在l长度修饰符,则相应的参数应为a   指向大小足以接受的字符数组的初始元素的指针   序列和终止空字符,将自动添加。

在你的情况下,

  • 提供%s是错误的,因为单个char是一个太短而无法扫描并保存数组的元素,它是以空值终止的。这会导致undefined behavior发生内存溢出。

  • %c应该“工作”,如果输入流没有从前一个 ENTER 按键存储newline 。如果清除所有待处理输入的输入流,您将看到它的工作原理。使用像

    这样的东西
    scanf(" %c", &b);   //the whitespace "eats up" all the previous whitespaces
    

    您可以查看我的this previous answer,了解详情。