为什么scanf对char输入表现得很奇怪?

时间:2011-08-17 20:42:26

标签: c linux

/* Write macro for the following : 

1. Arithmetic Mean of two no.
2. Absolute value of a no.
3. To convert a Uppercase letter to lower case.
4. To obtain bigger of two numbers.

*/

#include<stdio.h>

#define am(a,b) ((a+b)/2)
#define abs(a) (a>=0?a:-a)
#define ul(ch) (ch>=65 && ch<=96 ? ch+32 : ch)
#define bigger(a,b) (a>=b?a:b)

int main () {

    int x,y;
    char c;

    printf("\nEnter two numbers:");
            scanf("%d%d",&x,&y);

    printf("\nThe arithmetic mean of two numbers is %f",(float)am(x,y));

    printf("\nEnter the number:");
            scanf("%d",&x);

    printf("\nThe absolute value of the number is %d",abs(x));

    printf("\nEnter the character:");
            scanf("%c",&c);

    printf("\nThe letter in lower case  is %c",ul(c));

    printf("\nEnter two numbers:");
            scanf("%d%d",&x,&y);

    printf("\nThe bigger of two numbers is %d",bigger(x,y));


 return 0;

 }

一切正常,但程序不会因为输入字符而停止。

这是输出的快照....

  Enter two numbers:4
  5
  The arithmetic mean of two numbers is 4.000000

  Enter the number:-7   **/*After hitting enter here it reaches line no. 7 */** 
  The absolute value of the number is 7

  Enter the character:                                          
  The letter in lower case  is  

  Enter two numbers:4   **/*line no. 7*/**
  6

  The bigger of two numbers is 6

5 个答案:

答案 0 :(得分:3)

这是因为%d跳过了空格,但%c没有 - 换句话说。

%d将跳过输入流中任何前进的空白区域,然后输入指针将位于最后一位数字之后 - 这很可能是换行符。因此,当你来询问%c时,你实际上已经有了输入数据 - 这是你的换行符 - 这就是你将要阅读的内容。

通过在%c之前插入一个空格来改变你的scanf以要求它跳过空格,所以

   scanf(" %c",&c);

答案 1 :(得分:1)

%c读取任何字符,包括whitescape,因此它会“吃掉”换行符。

使用:scanf(" %c",&c);

答案 2 :(得分:1)

我认为这里的问题是你的scanf(“%c”,&amp; c)抓住当你按下Enter键进入-7时输入的回车。

在scanf之前放置一个getchar(或另一个scanf(“%c”,&amp; c)),你不应该有这个问题。

答案 3 :(得分:0)

那是因为在你的第一个scanf之后, enter 键仍在输入缓冲区中,下一个scanf将存储 enter x中的值。然后你的下一个printf将打印它 - 有效地移动到新的一行。

要解决此问题,您只需在每个getchar()之后添加scanf来电。

答案 4 :(得分:0)

scanf的一个常见问题是它不会消耗按Enter键导致的换行符。我通常在调用scanf

后使用以下宏来绕过它
#define consumeBuffer() while (getchar() != '\n');

当然,这并不总是你想要的,但在大多数情况下,它都可以解决问题。