getchar() != \n 和 while语句结合统计字符数,count = count + 1的作用
今天学了一个统计字符数的代码(使用的编译器是code blocks 20.03):
#include <stdio.h>
int main()
{
int count = 0 ;
printf("请输入英文字符:");
while ( getchar() != '\n')
{
count = count + 1;//这个算式不是用来计数的吗?为什么中文会计对应两个字符?
}
printf("你总共输入了%d个字符", count);
return 0;
}
本来我理解 count = count + 1 这个表达式是用来统计字符数的。
但是我在试着输入中文的时候,程序统计中文是2个字符,结果如下:
请输入英文字符:你好
你总共输入了4个字符
所以,我想重新了解一下这个程序是怎么统计字符的?能否对代码的每一个作用部位有一个详细解释?谢谢
对,这个程序就是用来统计字符个数的;
之所以你输入“你好”,
打印出是4,是因为每个中文占用2个字符;所以结果就是2*2 = 4;
番杰 发表于 2022-1-6 12:46
对,这个程序就是用来统计字符个数的;
之所以你输入“你好”,
打印出是4,是因为每个中文占用2个字符; ...
我知道一个中文是2个字符,但是我想知道这串代码为什么输出这个结果。
按理count = count + 1 的作用的只是循环体里面的一个计数器,我输入多少次它计多少次?难道 getchar函数是会将我的输入的汉字拆分成两个字符分别输入两次? 一只高傲的鹤 发表于 2022-1-6 15:01
我知道一个中文是2个字符,但是我想知道这串代码为什么输出这个结果。
按理count = count + 1 的作 ...
对,就是一个中文当成两个字符来看的,执行了两次count=count+1 番杰 发表于 2022-1-6 15:37
对,就是一个中文当成两个字符来看的,执行了两次count=count+1
有原理解释吗?我上面那个只是根据结果推导的猜想,我想知道是如何拆成两次?并且为什么执行两次 count = count + 1 ?一个汉字是一次输入进去的系统为什么会拆分成两次输入? 本帖最后由 番杰 于 2022-1-6 17:00 编辑
一只高傲的鹤 发表于 2022-1-6 16:27
有原理解释吗?我上面那个只是根据结果推导的猜想,我想知道是如何拆成两次?并且为什么执行两次 count = ...
在计算机中存储中文使用的编码规则是GB2312或GB2312-80,规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,连在ASCII里本来就有的数字、标点、字母都通通重新编了两个字节长的编码,这就是常说的“全角”字符,而原来在127号以下的那些就叫“半角”字符。
就这么说吧,字母和英文输入法下的一些标点符号都可以用ascii码形式表示,占一个字符,
而汉字和中文下的标点符号就用到了其他的解码标准来实现,像GB2312之类的标准,还有其他的感兴趣自行百度。它是占两个字符的,这也是为啥你打代码的时候,英文的分号可以,而中文的分号不可以,他俩代表着不同的数值;
再说回你的这个问题,你输入“你好”,在计算机看来就相当于输入了四个字符:“xxyy ”(具体是啥我也不知道,xx合在一起表示“你”,yy合在一起表示“好”,这个具体的值根据使用到解码规则有关),所以在循环的时候就一共执行了4次count++;所以结果是4.
另外,我之前已经说了中文占2个字节,你问有什么原理解释,但凡你想知道,百度一下什么都有了,学习不是只知道去问别人,而是自己去找答案的过程。
再另外,我之前也是单纯的知道中文占两个字符,也没具体的去了解过,为了你这个问题,我还特意去百度的,这些应该都是你自己去完成,而不是等着别人把答案告诉你。 中文为什么占两个字符我知道,在很久之前我了解过这个问题了,我并不是疑惑中文为什么占两个字符!
我想要了解的是:
1. 汉字的编码是一个整体,输入一个汉字为什么是计两次输入?
2. 像你说的,“你”二进制表示的可能是xx,xx是一起输入的,为什么程序为什么不是只读取x1,然后丢掉x2 ?
3. 有时候回复可能表述不是很清楚,但我从始至终表达的是想弄清楚这串代码运行的逻辑,这是我的目标。 在输入 “你好” 的时候,在没有按回车之前只是存在缓存区,while里面的count = count + 1;这句并没有执行。
在你按下回车之后,我们的输入才被送进去了输入缓冲区,这个时候,while循环才开始工作,内部机制才将一个中文转换成两个字符进行计算。
你可以将代码改成这样验证一下
#include "stdio.h"
int main()
{
int count = 0 ;
char c;
printf("请输入英文字符:");
while ( (c = getchar()) != '\n')
{
printf("%c\n",c);
count = count + 1;//这个算式不是用来计数的吗?为什么中文会计对应两个字符?
}
printf("你总共输入了%d个字符", count);
return 0;
}
关于getchar函数可参考这里getchar的使用 fishc_zmf 发表于 2022-1-7 14:21
在输入 “你好” 的时候,在没有按回车之前只是存在缓存区,while里面的count = count + 1;这句并没有执行 ...
懂了,你太优秀了,向你学习,验证的代码也很有用,谢谢! fishc_zmf 发表于 2022-1-7 14:21
在输入 “你好” 的时候,在没有按回车之前只是存在缓存区,while里面的count = count + 1;这句并没有执行 ...
还有个问题,那我输入的回车键是先缓存,还是直接执行while循环体?
1.如果是先缓存,那为什么我按回车程序直接运行了?
2.如果是直接执行,那while语言拿什么来结束循环?
我这个不是杠,只是有点没想明白。 一只高傲的鹤 发表于 2022-1-7 22:04
还有个问题,那我输入的回车键是先缓存,还是直接执行while循环体?
1.如果是先缓存,那为什么我按回车 ...
回车也是缓存了的而且也返回了。执行getchar函数时,在没有缓存区里没有回车(换行符)时程序就等着用户在输入按键,存在回车(换行符)后,才将缓存区的第一个字符返回,然后并且释放。
while结束可以不用'\n'结束,这个可以由你决定。
你可以试着写这个程序
while ( (c = getchar()) != 'z')
{
printf("%c\n",c);//或者putchar(c);
}
输入不带'z'的几个字符,相信你会有所发现,另外可以多变换一下程序验证下自己的猜想。 一只高傲的鹤 发表于 2022-1-7 22:04
还有个问题,那我输入的回车键是先缓存,还是直接执行while循环体?
1.如果是先缓存,那为什么我按回车 ...
你好好看看这个文章就懂了:输入缓冲区
回车相当于开关,输入回车,开始从输入缓冲区(或称是:输入流)中读取数据,注意回车也是存在其中的,getchar(每次读一个字符),你输入“你好回车”,在输入缓冲区里相当于“xxyy\n”,(有回车才开始读)
第一次循环:从输入流里读出x1(“你”的前一半),即ch = x1 ,不等于‘\n’,进入循环,执行count++,此时count = 1;
第二次循环:从输入流里读出x2(“你”的后一半),即ch = x2 ,不等于‘\n’,进入循环,执行count++,此时count = 2;
第三次循环:从输入流里读出y1(“好”前一半),即ch = y1 ,不等于‘\n’,进入循环,执行count++,此时count = 3;
第四次循环:从输入流里读出y2(“好”后一半),即ch = y2 ,不等于‘\n’,进入循环,执行count++,此时count = 4;
第五次循环:从输入流里读出\n(回车),即ch =‘\n’,退出循环,执行printf,此时count = 4; fishc_zmf 发表于 2022-1-8 09:54
回车也是缓存了的而且也返回了。执行getchar函数时,在没有缓存区里没有回车(换行符)时程序就等着用户在 ...
谢谢,学到了你解决问题的思路,楼下的贴输入缓冲区解释更清晰。 番杰 发表于 2022-1-8 10:02
你好好看看这个文章就懂了:输入缓冲区
回车相当于开关,输入回车,开始从输入缓冲区(或称是:输入流) ...
谢谢,很感谢你提供 输入缓冲区 资料,让我有一个新的认知。
但是关于我这个帖子的最佳答案是楼上那位好友前面回答的内容 fishc_zmf 发表于 2022-1-7 14:21
在输入 “你好” 的时候,在没有按回车之前只是存在缓存区,while里面的count = count + 1;这句并没有执行 ...
你好,本来我想选你这个贴子为 最佳答案 ,但是你里面有个概念说错了。不是回车之后数据才进入 “输入缓冲区”,而是我们键盘输入的数据先在“输入缓冲区”,按下回车之后才输送到程序中,建议你也可以看一下楼下好心人发的贴子链接。{:5_110:} fishc_zmf 发表于 2022-1-7 14:21
在输入 “你好” 的时候,在没有按回车之前只是存在缓存区,while里面的count = count + 1;这句并没有执行 ...
感谢你的链接呀,朋友!!
页:
[1]