HughKirk
匠川
采纳率100%
2016-09-19 14:05

关于C语言中的getchar(),小白请教一个问题。

10
已采纳

小白重新学C语言。
准备把K&R的The C programming language从头到尾学一遍。

然后今天敲到getchar()时,为了做练习1-6:验证getchar()!=EOF 是0还是1,我就写了下面的代码:

 main()
{
    int thischar,test=0;
    char flag = 0;

    while ((thischar=getchar()) != EOF)
    {   
        test = ((thischar = getchar()) != EOF);  //Q1.
        printf("The value of condition after putchar(): %d \n", test);
        flag = 1;
        //if ((thischar = getchar()) != EOF);   //test step
        while ((thischar = getchar()) != EOF && flag == 1)
        {
            putchar(thischar);
            //printf("\n");
        }
        flag = 0;

    }

输入“12345678”,输入就是“345678”。
缺少“12”。
我打开调试之后,发现thischar的值是这样变化的:

breakpoint1
breakpoint2

我查了ASCII码,对应的49,50就是1和2.
也就是说因为我多检测了两次

 (thischar = getchar()) != EOF

这个。就导致我输出少了两个字符。我之后又试了试,以此类推,条件数量增多少,输出的字符就会少多少。
网上说getchar()函数的代码是这样的:

    int  
    getchar ()  
    {  
      int result;  
      _IO_acquire_lock (_IO_stdin);  
      result = _IO_getc_unlocked (_IO_stdin);  
      _IO_release_lock (_IO_stdin);  
      return result;  
    }  

我也查了寄存器的说明,但是还是不明白,为什么会造成这样的情况。和getchar()这个函数的定义有关系吗?如果没有,那是哪里出的问题呢?

感激不尽!

追加:
谁能大概解释一下getchar()函数定义,用自然语言描述大概是什么样的过程?
以及:

 while ((thischar=getchar()) != EOF)
01064C89  mov         esi,esp  
01064C8B  call        dword ptr [__imp__getchar (0106916Ch)]  
01064C91  cmp         esi,esp  
01064C93  call        __RTC_CheckEsp (01061113h)  
01064C98  mov         dword ptr [thischar],eax  
01064C9B  cmp         dword ptr [thischar],0FFFFFFFFh  
01064C9F  je          main+0D3h (01064D33h)  
    {   
        test = ((thischar = getchar()) != EOF);  //Q1.
01064CA5  mov         esi,esp  
01064CA7  call        dword ptr [__imp__getchar (0106916Ch)]  
01064CAD  cmp         esi,esp  
01064CAF  call        __RTC_CheckEsp (01061113h)  
01064CB4  mov         dword ptr [thischar],eax  
01064CB7  cmp         dword ptr [thischar],0FFFFFFFFh  
01064CBB  je          main+69h (01064CC9h)  
01064CBD  mov         dword ptr [ebp-0E8h],1  
01064CC7  jmp         main+73h (01064CD3h)  
01064CC9  mov         dword ptr [ebp-0E8h],0  
01064CD3  mov         eax,dword ptr [ebp-0E8h]  
01064CD9  mov         dword ptr [test],eax

上面的EAX寄存器应该是存了getchar()的返回值,那后面这个值是怎么样被后续操作抹掉的?我不太懂。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

  • u014327136 yukangliu 5年前

    while ((thischar=getchar()) != EOF)
    {

    test = ((thischar = getchar()) != EOF); //Q1.
    这两行代码在你输入1和2时分别被赋值1和2;
    while ((thischar = getchar()) != EOF && flag == 1)
    {
    putchar(thischar);
    这几行代码运行是才是输出后面的赋值3,4 ,5,6,7,8;
    如果需要更改,可改成:

    main()
    {
        int thischar,test=0;
        char flag = 0;
    
        while ((thischar=getchar()) != EOF)
        {   
                putchar(thischar);
            test = ((thischar = getchar()) != EOF);  //Q1.
                    putchar(thischar);
           // printf("The value of condition after putchar(): %d \n", test);
            flag = 1;
            //if ((thischar = getchar()) != EOF);   //test step
            while ((thischar = getchar()) != EOF && flag == 1)
            {
                putchar(thischar);
                //printf("\n");
            }
            flag = 0;
    
        }
    }
    
    

    这样应该可以看明白吧。

    点赞 1 评论 复制链接分享
  • weixin_36183906 weixin_36183906 5年前

    每执行一次getchar,就会取出一个值,1和2你取出来后没有打印!也就是说,你在那个循环打印之前,已经执行了2次getchar

    点赞 评论 复制链接分享
  • waterhexuan 编天码地 5年前

    getchar 本来就是执行一次 少一个啊 没看懂你这程序有什么异常啊

    点赞 评论 复制链接分享