【C】C语言中getchar()的使用

参考程序

内容参考Dennis M.Rithchie编写的《C程序设计语言 第二版》
在这里插入图片描述

文件复制

#include<stdio.h>
/*将输入复制到输出*/
int main()
{
  int ch;
  while((c=getchar())!=EOF)
    putchar(ch);
}

int c: char类型专门用于存储字符型数据,当然任何整型(int)也可用于存储字符型数据。这里之所以不把c声明成char类型,是因为它必须足够大,除了能存储任何可能的字符外还要能存储文件结束符EOF

EOF:文件结束符,Windows下为组合键Ctrl+Z, Unix/Linux下为组合键Ctrl+D。

从运行结果上看,getchar()并不是你每按一次键就执行一次,而是在键入回车键后整体运行的结果。

博主可乐’给出了这种现象的解释:键盘输入的字符都存到缓冲区内,一旦键入回车,getchar()就进入缓冲区读取字符,一次只返回第一个字符作为getchar函数的值,如果有循环或足够多的getchar语句,就会依次读出缓冲区内的所有字符直到’\n’。

整个过程为
1.abcdefg 键入进入缓冲区
2.abcdefg+enter 键入回车 getchar()进入缓冲区读取字符
3.getchar()每读取缓冲区一个字符,while判断为真,putchar()输出输出该字符,回车也被读取输出。

单词计数

#include<stdio.h>
#define IN 1   /*在单词内*/
#define OUT 0   /*在单词外*/
int main()
{
  int ch,nw,nl,nc,state;
  state=OUT;
  while((ch=getchar())!=EOF){
    ++nc;
    if(ch=='\n')
      ++nl;
    if(ch==' '||ch=='\n'||ch=='\t')
      state=OUT;
    if(state==OUT){
      state=IN;
      ++nw;
    }
   
  }
  printf("%d %d %d\n",nl,nw,nc);
}

读取字符数组设计getline()

#include<stdio.h>
/*按行读取字符数组,最后两位留为回车和空*/
#define MAXLINE 4   /*允许的输入行的最大长度*/
int main()
{
  int ch,i;
  for(i=0;i<MALINE-1 && (ch=getchar())!=EOF && ch!='\n';++i)
    s[i]=ch;
  if(ch='\n'){
    s[i]=ch;
    ++i;
  }
  s[i]='\0';
  printf('%s %d',s,i);
}

设置字符数组最大长度为4

输入为ab+回车
在这里插入图片描述
1.ab键入缓冲区
2.ab+enter 键入回车,getchar()进入缓冲区读取字符,for循环开始执行ch=getchar()
3.getchar()读取 b后 i=2
4.getchar()读取回车ch=’\n’,i=2,跳出循环
5.if(ch==’\n’)条件成立 s[2]=ch=’\n’ i=3
6.s[3]=’\0’
7.最终结果 s=[a b ‘\n’ ‘\0’]
打印时 a b+回车(转至次行)空+3(i)

输入为abcdef+回车
在这里插入图片描述
1.abcdef键入缓冲区
2.abcedf+enter 键入回车 for循环中getchar()进入缓冲区读取字符,for循环开始执行ch=getchar()
3.getchar()读取c至ch后 c的内容被存入s[2] 之后 i=3
4.此时 ch=‘c’不等于’\n’
5.s[3]=’\0’
6.最终结果 s=[a b c ‘\0’]
打印时 a b c 空 3

getline()函数

int getline(char s[], int lim)
{
  int ch,i;
  for(i=0;i<lim-1 && (ch=getchar())!=EOF && ch!='\n';++i) 
    s[i]=ch;  /*回车会被读入c但是不会存入s[i]*/
  if(ch=='\n'){
    s[i]='\n';
    ++i;
  }
  s[i]='\0';
}

关于Ctrl+Z

这里引用博主乌托对Ctrl+Z的理解

Ctrl+Z的ASCII码值

#include<stdio.h>
int main()
{
  int c;
  while((c=getchar())!=EOF)
  printf('%c %d\n',c,c);
}

输入ab ctrl+z
在这里插入图片描述
可见在终端windows系统中ctrl+z的ASCII值为26,键入ctrl+z其实输入的是一个ASCII值为26的字符。

对于单词计数程序

#include<stdio.h>
#define IN 1   /*在单词内*/
#define OUT 0   /*在单词外*/
int main()
{
  int ch,nw,nl,nc,state;
  state=OUT;
  while((ch=getchar())!=EOF){
    ++nc;
    if(ch=='\n')
      ++nl;
    if(ch==' '||ch=='\n'||ch=='\t')
      state=OUT;
    if(state==OUT){
      state=IN;
      ++nw;
    }
   
  }
  printf("%d %d %d\n",nl,nw,nc);
}

Ctrl+Z前没有其他字符

输入abcd+回车+(ctrl+z+回车)
在这里插入图片描述
而当ctrl+z前面没有其他字符时,系统此时会检测到ctrl+z,此时getchar()就会读取失败,返回EOF。所以如果需要终端输入ctrl+z终止输入,需要另起一行输入ctrl+z才行。

Ctrl+Z前有其他字符

输入abcd+(ctrl+z+回车)+回车+(ctrl+z+回车)
在这里插入图片描述
ctrl+z前面有其他字符时,此时系统认为缓冲区中有可读的数据,系统不会检测ctrl+z(因为有要读的数据,还不能认为到了流的末尾)

在while循环中添加显示

printf("%c",c);

输入abcd+(ctrl+z+回车),显示后+(ctrl+z+回车)
在这里插入图片描述
1.对于前面有数据的^z getchar()将其当做ASCII码为26的字符读入ch,显示为‘->’
2.第一个^z后的回车没有读入ch中

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值