鱼C论坛

 找回密码
 立即注册
查看: 1013|回复: 7

[已解决]程序运行时的问题

[复制链接]
发表于 2020-9-21 14:00:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>
#include <string.h>
static int letters = 0,nums = 0,spaces = 0,others = 0;
void tongji(char *p);
int main()
{
        int i = 0;
        char *p,array[100];
                p = array;
                while(getchar() != '\n')
                {
                    *(p + i) = getchar();
                        i++;
                }
        tongji(p);
        printf("字母个数 = %d\n",letters);
        printf("数字个数 = %d\n",nums);
        printf("空格个数 = %d\n",spaces);
        printf("其他字符个数 = %d\n",others);
        printf("\n");
}

void tongji(char *p)
{
    int i,len;
        char ch;
    char array[50];
        len = strlen(array);
        for(i = 0;i < len;i++)
        {
            ch = *(p + i);
                if(ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122)
                {
                    letters += 1;
                }
                else if(ch >= 48 && ch <= 57)
                {
                    nums += 1;
                }
                else if(ch == ' ')
                {
                    spaces += 1;
                }
                else
                {
                    others += 1;
                }
        }

}

程序步进运行时正常,正常运行时,需要按两次回车键,怎么修改?
最佳答案
2020-9-21 19:46:18
程序步进运行时正常,正常运行时,需要按两次回车键


估计你是没有理解其中的原理:

    (1)键盘缓冲区 和 输入流数据缓冲区
     当我们在键盘上敲键时,敲入的一个个键值都暂存在键盘缓冲区里,只有遇到回车键(回车键也是字符,\n )时,敲入的键值才从键盘缓冲区送入到输入流数据缓冲区。

     (2)getchar() 是到输入流数据缓冲区去读取一个字符,当输入流数据缓冲区没有数据时,读语句就等待,当输入流数据缓冲区有数据时,就读最先进来的那个字符。读一个,就从输入流数据缓冲区里清除掉这个字符。getchar() != '\n' 是进一步判断刚读入的这个字符是不是回车键。

     (3)while (getchar() != '\n' ) continue;与 while (getchar() != '\n' ) 空语句 ; 作用相同,就是 循环着到输入流数据缓冲区去读取一个一个字符,只要读到的不是 '\n', 就继续读 (读一个清除一个),直到读到 '\n'。其作用等价于 “清除输入流数据缓冲区”。

     (4)输入流数据缓冲区被清除后,程序再次等待键盘缓冲区把东西送过来。而键盘缓冲区等待用户敲入字符,此时若键盘缓冲区送过来的 '\n' ,则结束这个 while 循环。

      而 *(p + i) = getchar() 将 getchar() 读取键盘输入的值赋给 (p + i) 这个数组单元,然后再判断 (p + i) 这个单元的值 *(p + i) 是否是 '\n',如果不是回车键,则循环继续,如果是回车键,则结束循环。

      以上就是为什么你调试程序时正常,正式运行时,在输入完字符后敲回车键确认(注意,此时敲的回车键只是确认输入)后,还需敲一次回车键的原因。

      程序的修改,楼上的两位已经说的很清楚了,我就不重复了。

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-21 14:05:02 | 显示全部楼层
本帖最后由 巴巴鲁 于 2020-9-21 19:36 编辑

while里的getchar();删掉换成12行的代码
再把12行代码删掉试试看,我现在不方便上机操作
----------------------------------------------------------------------
其实不是输入两次回车才结束,如果你输入1 3(后面输入任意字符),再接着输入回车,程序也会结束
为什么呢?因为你输入的字符被while里getchar()给缓冲掉了,相当于输入的字符没有了意义
这也就是为什么使用getchar函数赋值时要"ch = getchar();"
如果只写"getchar();"程序会吃掉你输入的那个字符,这也是getchar();在某种情况下会用的一种用法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-21 14:05:37 | 显示全部楼层
#include <stdio.h>
#include <string.h>
static int letters = 0, nums = 0, spaces = 0, others = 0;
void tongji(char* p);
int main()
{
    int i = 0;
    char* p, array[100];
    p = array;
    while ((*(p + i) = getchar()) != '\n')
    {
        i++;
    }
    *(p + i) = '\0';
    tongji(p);
    printf("字母个数 = %d\n", letters);
    printf("数字个数 = %d\n", nums);
    printf("空格个数 = %d\n", spaces);
    printf("其他字符个数 = %d\n", others);
    printf("\n");
}

void tongji(char* p)
{
    int i, len;
    char ch;
    len = strlen(p);
    for (i = 0; i < len; i++)
    {
        ch = *(p + i);
        if (ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122)
        {
            letters += 1;
        }
        else if (ch >= 48 && ch <= 57)
        {
            nums += 1;
        }
        else if (ch == ' ')
        {
            spaces += 1;
        }
        else
        {
            others += 1;
        }
    }

}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-21 19:46:18 | 显示全部楼层    本楼为最佳答案   
程序步进运行时正常,正常运行时,需要按两次回车键


估计你是没有理解其中的原理:

    (1)键盘缓冲区 和 输入流数据缓冲区
     当我们在键盘上敲键时,敲入的一个个键值都暂存在键盘缓冲区里,只有遇到回车键(回车键也是字符,\n )时,敲入的键值才从键盘缓冲区送入到输入流数据缓冲区。

     (2)getchar() 是到输入流数据缓冲区去读取一个字符,当输入流数据缓冲区没有数据时,读语句就等待,当输入流数据缓冲区有数据时,就读最先进来的那个字符。读一个,就从输入流数据缓冲区里清除掉这个字符。getchar() != '\n' 是进一步判断刚读入的这个字符是不是回车键。

     (3)while (getchar() != '\n' ) continue;与 while (getchar() != '\n' ) 空语句 ; 作用相同,就是 循环着到输入流数据缓冲区去读取一个一个字符,只要读到的不是 '\n', 就继续读 (读一个清除一个),直到读到 '\n'。其作用等价于 “清除输入流数据缓冲区”。

     (4)输入流数据缓冲区被清除后,程序再次等待键盘缓冲区把东西送过来。而键盘缓冲区等待用户敲入字符,此时若键盘缓冲区送过来的 '\n' ,则结束这个 while 循环。

      而 *(p + i) = getchar() 将 getchar() 读取键盘输入的值赋给 (p + i) 这个数组单元,然后再判断 (p + i) 这个单元的值 *(p + i) 是否是 '\n',如果不是回车键,则循环继续,如果是回车键,则结束循环。

      以上就是为什么你调试程序时正常,正式运行时,在输入完字符后敲回车键确认(注意,此时敲的回车键只是确认输入)后,还需敲一次回车键的原因。

      程序的修改,楼上的两位已经说的很清楚了,我就不重复了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-21 19:49:50 | 显示全部楼层
getchar一个简单的用法:
#include <stdio.h>
int main(void)
{
                int num;
                char ch;
                printf("请输入一个数字:");
                scanf("%d",&num);
                
                // getchar()简单用法,可以看看有没有这句程序的输出不同 
                getchar(); // 这里就是缓冲回车符 
                
                printf("请输入任意字符:(只有在输入回车才会打印)\n");
                if((ch = getchar()) == '\n')
                {
                        printf("没想到吧!我直接输出了\n");
                }
                
                return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-21 23:21:53 | 显示全部楼层
巴巴鲁 发表于 2020-9-21 14:05
while里的getchar();删掉换成12行的代码
再把12行代码删掉试试看,我现在不方便上机操作
--------------- ...

谢谢你讲解!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-21 23:24:21 | 显示全部楼层

谢谢! 谢谢! 有鱼还不行啊,我不可能每次都要求助,我还是想要渔
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-21 23:25:40 | 显示全部楼层
风过无痕1989 发表于 2020-9-21 19:46
估计你是没有理解其中的原理:

    (1)键盘缓冲区 和 输入流数据缓冲区

谢谢! 你的讲解,我彻底明白了getchar()的用法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-13 02:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表