日志档案

发表于 2007-1-28 17:35:31

1

标签: 无标签

关于scanf函数的一个问题

朋友问到一个关于scanf函数使用的问题:在一个
while(1)
{
   scanf("%c",&p);
    if( p = 'q')
   break;
}之中,第一次scanf能很好的执行,第二次则不行,第三次又可以,第四次又不行........

通过搜索网页,发现scanf有许多的bug,上面的是其中的一个.所于下面的问题:
摘自http://dev.csdn.net/article/49/49605.shtmscanf()函数释疑

键盘缓冲区残余信息问题
#include
int main()
{
    int a;
    char c;

    do
    {
        scanf("%d",&a);
        scanf("%c",&c);
        printf("a=%d     c=%c\n",a,c);
        /*printf("c=%d\n",c);*/
    }while(c!='N');
}

   scanf("%c",&c);这句不能正常接收字符,什么原因呢?我们用printf("c=%d\n",c);将C用int表示出来,启用 printf("c=%d\n",c);这一句,看看scanf()函数赋给C到底是什么,结果是 c=10 ,ASCII值为10是什么?换行即\n.对了,我们每击打一下"Enter"键,向键盘缓冲区发去一个“回车”(\r),一个“换行"(\n),在这里 \r被scanf()函数处理掉了(姑且这么认为吧^_^),而\n被scanf()函数“错误”地赋给了c.

解决办法:可以在两个scanf()函数之后加个fflush(stdin);,还有加getch(); getchar();也可以,但是要视具体scanf()语句加那个,这里就不分析了,读者自己去摸索吧。但是加fflush(stdin);不管什么情况都可行。

函数名: fflush
功  能: 清除一个流
用  法: int fflush(FILE *stream);

#include
int main()
{
    int a;
    char c;

    do
    {
        scanf("%d",&a);
        fflush(stdin);
        scanf("%c",&c);
        fflush(stdin);
        printf("a=%d     c=%c\n",a,c);

    }while(c!='N');
}      

这里再给一个用“空格符”来处理缓冲区残余信息的示例:

运行出错的程序:

#include
int main()
{
    int i;
    char j;
    for(i = 0;i < 10;i++)
    {
        scanf("%c",&j);/*这里%前没有空格*/
    }
}

使用了空格控制符后:

#include
int main()
{
    int i;
    char j;
    for(i = 0;i < 10;i++)
    {
        scanf(" %c",&j);/*注意这里%前有个空格*/
    }
}

    可以运行看看两个程序有什么不同。(空格符号清除了残余信息的作用,scanf能够正确的工作了)


一个好的函数指针应用的程序

//compiler: win-tc v1.91
//created by cgha
#include <stdio.h>


typedef void(*pfun)(void);// pointer to the function

struct cmdEntry
{
    char * cmdname;
    pfun pfun1;
    char * cmdcomment;
}*pStruct;

void quit()
{
    printf("%s","i am quit function\r\n");
}

void reboot()
{
    printf("%s","i am reboot function\r\n");
}


struct cmdEntry cmdList[] =
{
    /* cmdchar  cmdhandler help */
    { "Q", quit,"quit funcion"    },
    { "R", reboot,"reboot function" },
};


void main()
{
    char cmd;
    pStruct= &cmdList[0];
    printf("cmd1: %s    ", pStruct->cmdname);
    printf("%s", pStruct->cmdcomment);
    printf("%s" ,"\r\n");
   
    pStruct++;
   
    printf("cmd2: %s    ", pStruct->cmdname);
    printf("%s", pStruct->cmdcomment);
    printf("%s" ,"\r\n");
   
    printf("Please input the number of function you want to exe(Q/R)\r\n");
   
   
    scanf("%c",&cmd);
   
    switch(cmd)
    {
    case 'q':
    case 'Q':
        pStruct--;
        (pStruct->pfun1)();
        getchar();//作用可能是用来屏蔽缓存中回车键带来的问题
        break;
       
    case 'r':
    case 'R':
        (pStruct->pfun1)();
        getchar();
        break;
       
    default:printf("error cmd");
       
        getchar();
    }
}

系统分类: 软件开发   |   用户分类: 编程--C语言   |   来源: 整理   |   【推荐给朋友】

    阅读(631)    回复(0)  

投一票您将和博主都有获奖机会!