这篇文章要探讨的是“getchar()函数的详解以及使用时需要注意的一些细节”。涉及getchar()函数的应用和需要注意的问题。属于C语言基础篇(持续更新)。

在C语言的学习过程中,我们常常需要接收键盘的输入,在接收键盘输入的过程中涉及到的函数通常有三个getchar()scanf()fgets()。这三个函数各自的功能各不相同,需要我们根据不同的需求条件来选择不同的输入接收函数。而在这三个函数的使用过程中,有一些细节需要我们注意一下。所以接下来的三篇文章就是分别介绍这三个函数的。

getchar()(函数原型:int getchar(void))


一般用法:

char c = getchar();

getchar()函数的作用很简单,从输入缓存区中读取一个字符,读取到的字符储存在返回值里面。


getchar()函数注意事项1:

对于你输入的任何数据,getchar() 都会把它们当作是字符来处理,而且每次只获取一个字符。例如你输入“11”,getchar() 并不会把它当做“11”来处理,而是把它当做两个‘1’来处理。同理,你输入“3.14”它也不会当成“3.14”来处理而是当做‘3’、‘.’、‘1’、‘4’来处理,需要特别说明的是,像是换行符(\n)、回车符\归位符(\r)、缩进符(\t)之类的转义字符,它们虽然在代码中的表示和我们平时说明中用的是两个字符。但实际上它们在机器中存储和还是以一个字符来存储。所以别想着你敲个回车它能给你输入‘/’和‘n’。我们表示是这么表示,但在机器内部它就还是一个字符而已。

对于换行符(\n)和回车符(\r)的区别我在这里简单说一下。

换行符(\n)的作用是换一行输出。回车符(\r)的作用是把光标回到该行的行首。这两者的概念之所以有很多人会疑惑,这是由于我们平时的习惯称呼导致的。我们习惯性的把键盘上面那个换行回车键称为回车键,事实上它应该是两个键的混合(\r\n)。

同时也因为我们现在的开发环境便捷导致的,在一般的开发环境下面换行符(\n)就已经相当于同时具备换行回车(\r\n)的功能了,所以我们平时对于(\n)用的就比较多,(\r)就比较少用了。

但是如果在一些不那么高级的开发环境(例如小型嵌入式系统)下面的话,情况就不一样了,换行符(\n)就仅仅只是换行而已,你原本的光标在一行的哪个位置,就还在新行的哪个位置。你若想要光标回到行首,你就得手动输出回车符(\r)。


getchar()函数注意事项2:

getchar()函数是会阻塞等待的。在程序调用getchar()函数的时候如果缓存区中没有数据的话,getchar()函数便会阻塞等待用户的输入。


getchar()函数注意事项3:

getchar()的返回值做判断的时候,需要考虑到是否存储保留的问题。无论你是否接收getchar()的返回值,只要你调用了getchar(),那么缓存区中就会被读取走一个字符。

这里用一个我曾经犯错误的例子来说明一下:

#include <stdio.h>
int main(void)
{
char c[100] = {0};//创建一个数组来存储输入
int i = 0;//记录一共输入了几个字符,方便后面输出。
while(1)
{
if(getchar() == ‘\n’)//先判断输入的是否是回车键
break;
c[i] = getchar();//再把判断好的输入值存储起来
i++;
}
for(int k = 0;k < i;k++)
printf("%c", c[k]);//把存储的值输出
printf("\n");
return 0;
}

这个程序所要实现的功能是“程序运行之后,持续的读取键盘的输入一直到用户输入换行符为止,然后退出循环输出读取到的内容”。


先看一下这个程序出现的问题吧:

  • 运行的时候如果你输入数据的字符个数为单数的时候,你需要输入两次回车才能结束程序,而且程序读取到的输入总是用户输入的一半,而且是隔一个读取一个那种,最后面还多输出一个回车。

  • 运行的时候如果你输入数据的字符个数为双数的时候,就还算正常,仅仅只是输入少一半而已。


其实仔细分析一下,就不难看出,这两种情况是可以归类为一种情况的。如果你把第一种情况中第一次输入的回车也看作一个字符的话,你就会发现,只有当你输入数据的字符个数为双数的时候,你下一个输入的回车才能结束程序(也就是说如果我只在单数的时候输入回车,那么这个程序就会一直运行下去,直到一开始给的数组内存大小不够,程序访问到了非法内存才会结束)。也是因为第一次输入的回车被算进整体输入里面去了,才导致了第一种情况的时候结尾多了个换行。


再说一下原因吧:

出现这种情况的原因很简单,相信不少人也已经看出来了。在这个例子中我在判断输入是否是“\n”的时候就已经读取走一个字符了,后面再存储的时候已经是第二个字符了,所以就造成了“读取到的输入只有实际输入的一半这种情况”。


解决办法:

解决办法也不难,牺牲一个临时变量来存储输入的数据,再判断是否是回车键即可。

#include <stdio.h>
int main(void)
{
char c[100] = {0};//储存输入数据用的数组
int i = 0;//记录输入的字符个数方便输出
char z = 0;//解决方法就是加入临时变量来先储存再判断
while(1)
{
z = getchar();//先储存输入的数据
if(z == ‘\n’)//再判断
break;//如果是回车就退出循环
c[i] = z;//如果不是回车就存储
i++;//计数加一
}
for(int k = 0;k < i;k++)
printf("%c", c[k]);//把储存的数据输出
printf("\n");
return 0;
}

再附上这个例子的精简版代码:

#include <stdio.h>
int main(void)
{
int i = 0;
char c[100] = {0};
while((c[i++] = getchar()) != '\n');
for(int k = 0;k <= i;k++)
printf("%c", c[k]);
return 0;
}

getchar()函数注意事项4:

遇到再更新。。。


原博客始发于CSDN,在如今博客界的转载抄袭泛滥的环境下,原创不易,点个赞再走呗。以下是博客首页的链接。


零BUG是原则性问题。

最新文章

  1. CSharpGL(26)在opengl中实现控件布局/渲染文字
  2. 【前端积累】常用事件的js公用方法
  3. elasticsearch一些常用的配置
  4. 免费开源分布式系统日志收集框架 Exceptionless
  5. LeetCode Find All Numbers Disappeared in an Array
  6. 服务器asp.net 3.5 HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效。
  7. easyui form 方式提交数据
  8. R如何检验类别变量(nominal variable)与其他变量之间的相关性
  9. Linux 字符设备控制技术
  10. shell bash判断文件或文件夹是否存在
  11. ListBoxControl 删除选择的项的方法
  12. 【JS控制图片显示的大小(图片等比例缩放)】
  13. SDL 2.0 如何在 windows 上使用?
  14. Java遍历文件目录
  15. XML相关知识
  16. 小米6X手机解锁(bl锁)
  17. web前端开发过程遇到的问题及解决方式(一)
  18. socket流程
  19. SharePoint REST 服务获取讨论版问题
  20. Java 面向对象编程小练习(曾经)

热门文章

  1. Git使用的一些文章
  2. llinux day02 基础操作 帮助 文件管理 马
  3. 安装.msi格式安装包
  4. K8s试验环境搭建(一)
  5. dp泄露
  6. Expected indentation of 2 spaces but found 4
  7. python如何实现对word内段落文本及表格的读取
  8. MAC截图快捷键有哪些?
  9. js字符串截取(获取指定字符后面的所有字符内容)
  10. 「SOL」序列 (LOJ/NOI2019)