第二十一讲:标准输入流

第二十一讲:标准输入流

本讲基本要求

    * 掌握:标准输入在C++程序中的应用。
重点、难点
    ◆标准输入在C++程序中的应用。

标准输入流是从标准输入设备(键盘)流向程序的数据。

一、cin流

   在头文件iostream.h中定义了cin,cout,cerr,clog4个流对象,cin输人流,cout,cerr,clog是输出流。关于coutl,cerr,clog的使用方法已在上一讲中介绍。
   cin是istream类的对象,它从标准输入设备(键盘)获取数据,程序中的变量通过流提取符“>>”从流中提取数据。流提取符“>>”从流中提取数据时通常跳过输人流中的空格、tab键、换行符等空白字符。注意:只有在输入完数据再按回车键后,改行数据才被送人键盘缓冲区,形成输入流,提取运算符“>>”才能从中提取数据。需要注意保证从流中读取数据能雁常进行。
例如    int a,b;
         cin>>a>>b; // 若从键盘上输入 21 abc出错
说明:
   只有在正常状态时,才能从输入流中提取数据。
   当遇到无效字符或遇到文件结束符(不是换行符,是文件中的数据已读完)时,输人流cin就处于出错状态,即无法正常提取数据。此时对cin流的所有提取操作都将终止。在IBMPC及其兼容机中,以Ctrl+Z表示文件结束符。在UNIX和Macintosh系统中,以Ctrl+D表示文件结束符。当输人流cin处于出错状态时,如果测试cin的值,可以发现它的值为false(假),即ciacin为O值。如果输入流在正常状态,cin的值为true(真),即cin为一个非0值。可以通过测试cin的值,判断流对象是否处于正常状态和提取操作是否成功。

如:    if(!cin) //流cin处于出错状态,无法正常提取数据
      cout<<"error”;

例5 通过测试cin的真值,判断流对象是否处于正常状态。
#include <iostream>
using namespace std;
int main()
 { float grade;
   cout<<"enter grade:";
   while(cin>>grade) //如果能从cin流读取数据cin的值为真,执行循环体
   { if(grade>=85) cout<<grade<<" GOOD!"<<endl;
     if(grade<60) cout<<grade<<" fail!"<<endl;
     cout<<"enter grade:";
   }
   cout<<"The end."<<endl;
   return 0;}

   流提取符“>>”不断地从输人流中提取数据(每次提取一个浮点数),如果成功,就赋给变量grade,此时cin为真,若不成功则cin为假。如果输入文件结束符,表示数据已完。

运行情况如下:
   enter grade:67
   enter grade:89/
   89 GOOD!
   enter grade:56s/
   56 fail!
   entergrade:100
   100 GOOD!
   enter grade:^Z //输入文件结束符
   The end.

在遇到文件结束符时,程序结束。如果某次输入的数据为: enter grade:100/2 (回车)
流提取符“>>”提取100,赋给grade,进行if语句的处理。然后再遇到“/”,认为是无效字符,cin返回o。循环结束,输出"Theend.”。
在不同的C++系统下运行此程序,在最后的处理上有些不同。以上是在GCC环境下运行程序的结果,如果在VC++环境下运行此程序,在键人Ctrl+z时,程序运行马上结束,不输出”Theend.”。

二、 用于字符输入的流成员函数

除了可以用CIB输入标准类型的数据外,还可以用istream类流对象的一些成员函数,实现字符的输入。

1、用get函数读入一个字符
流成员函数get有3种形式:无参数的,有一个参数的,有3个参数的。

(1)不带参数的get函数

其调用形式为: cin.get() //用来从指定的输人流中提取一个字符(包括空白字符)函数的返回值就是读入的字符。

   若遇到输入流中的文件结束符,则函数值返回文件结束标志EOF(End Of File),一般以-1代表EOF,用-1而不用0或正值,是考虑到不与字符的ASCII代码混淆,但不同的C++系统所用的EOF值有可能不同。

例6 用get函数读人字符。
   从键盘输入一行字符,用cin.get()逐个读人字符,将读入字符赋给字符变量c。如果c的值不等于EOF(EOF是在lostream头文件中定义的符号常量,代表-1),表示已成功地读入一个有效字符,然后通过put函数输出该字符。

#include <iostream>
using namespace std;
int main()
 { char c;
   cout<<"enter a sentence:"<<endl;
   while((c=cin.get())!=EOF)
   cout.put(c);
   return 0; }

运行情况如下:
   enter a sentence:
   I study C++ very hard. (输入一行字符)
   I study C++ very hard. (输出该行字符)
   ^Z/(程序结束)

   C语言中的getchar函数与流成员函数cin.get()的功能相同,C++保留厂C的这种用法,可以用getchar(c)从键盘读取一个字符赋给变量c。

(2)有一个参数的get函数

其调用形式为
   cin.get(ch)// 其作用是从输人流中读取一个字符,赋给字符变量ch。

   如果读取成功则函数返回非。值(真),如失败(遇文件结束符)则函数返回。值(假)。例6可以改写如下:

#include<iostream>
int main()
 { char c;
   cout<<"enter a sentence:"<<endl;
   while(cin.get(c)) //读取—个字符赋给字符变量c,如果读取成功,cin.get(c)为真
    { cout.put(c);}
   cout<<"end"<<endl:
   return 0;}

(3)有3个参数的get函数

其调用形式为
     cin.get(字符数组,字符个数n,终止字符)
   
     cin.get(字符指针,字符个数n,终止字符)

   其作用是从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组),如果在读取n-1个字符之前遇到指定的终止字符,则提前结束读取。如果读取成功则函数返回非0值(真),如失败(遇文件结束符)则函数返回0值(假)。再将例6改写如下:

#include<iostream>
using namespace std;
int main()
 { char ch[20];
   cout<<"enter a sentence:”<<endl;
   cin.get(ch,10,'\n'); //指定换行符为终止字符
   cout<<ch<<endl;
   return(); }

运行情况如下:
   enter a sentence:
   I study C++ very hard./
   I study C

    在输人流中有22个字符,但由于在get函数中指定的n为10,读取n-1个(即9个)字符并赋给字符数组ch中前9个元素。有人可能要问:指定n=10,为什么只读取9个字符呢?因为存放的是一个字符串,因此在9个字符之后要加入一个字符中结束标志 '\0',实际上存放到数组中的是10个字符。请读者思考:如果不加入字符串结束标志,会出现什么情况?结果是:在用"cout<<ch”;输出数组中的字符时,不是输出读人的字符串,而是数组中的全部元素。读者可以上机检查一下ch[9](即数组中第10个元素)的值是什么?
如果输入: abcde/

2.用成员函数getline函数读入一行字符
   getline函数的作用是从输人流中读取一行字符,其用法与带3个参数的get函数类 似。

   即: cin.getline(字符数组(或字符指针),字符个数n,终止标志字符)

例7 用getline函数读人一行字符。
#include <iostream>
using namespace std;
int main()
 { char ch[20];
   cout<<"enter a sentence:"<<endl;
   cin>>ch;
   cout<<"The string read with cin is:"<<ch<<endl;
   cin.getline(ch,20,'/');//读19个字符或遇'/'结束
   cout<<"The second part is:"<<ch<<endl;
   cin.getline(ch,20); //读l9个字符或遇'/n',结束
   cout<<"The third part is:"<<ch<<endl;
   return 0; }

程序运行情况如下:
enter a sentence:I like C++./I study C++./I am happy.(回车)
The stung read with cin is:I
The second part is:like C++.
The third part is:I study C++./I am h


有几点说明并请思考:
   1、如果第2个cin.getline函数也写成cin.getline(ch,20,'/'),输出结果会如何?
此时最后一行的输出为:
The third part is:I study C++

   2、如果在用cin.getline(ch,20,'/')从输入流读取数据时,遇到回车键('\n'),是否结束读取?结论是此时'/n'不是结束标志。'/n'被作为一个字符被读人。

   3、用gefiine函数从输入流读字符时,遇到终止标志字符时结束,指针移到该终止标志字符之后,下一个getline函数将从该终止标志的下一个字符开始接着读人,如本程序运行结果所示那样。如果用cln.get函数从输人流读字符时,遇终止标志字符时停止读取,指针不向后移动,仍然停留在原位置。下一次读取时仍从该终止标志字符开始。这是getline函数和get函数不同之处。   
   因此用get函数时要特别注意,必要时用其他方法跳过该终止标志字符(如用下面介绍的ignore函数。但一般来说还是用getline函数更方便。

   4、请比较用"cin<<”和用成员函数cin.getline()读数据的区别。用"cin<<”读数据时以空白字符(包括空格、tab键、回车键)作为终止标志,而用cln.gefline()读数据时连续读取一系列字符,可以包括空格。用"cin<<”可以读取C++的标准类型的各类型数据(如果经过重载,还可以用于输入自定义类型的数据),而用cin.getline()只用于输入字符型数据。

三、istrearn类的其他成员函数

   除了以上介绍的用于读取数据的成员函数外,lstream类还有其他在输入数据时用得着的一些成员函数。常用的有以下几种:

1.eof函数
   eof是end of file的缩写,表示“文件结束”。从输人流读取数据,如果到达文件末尾(遇文件结束符),eof函数值为非零值(表示真),否则为o(假)。这个函数是很有用的,经常会用到。

例8 逐个读入一行字符,将其中的非空格字符输出。
#include <iostream>
using namespace std;
int main()
 { char c;
   while(!cin.eof())    //eof()为假表示未遇到文件结束符
   if((c=cin.get())!=' ')//检查读入的字符是否为空格字符
      cout.put(c);
   return 0; }

运行情况如下:
   C++ is very interesting./
   C++ is veryinteresting.
   ^z(结束)

2.peek函数
   peek是“观察”的意思,peek函数的作用是观测下一个字符。其调用形式为
      c=cin.peek();
   cin.peek函数的返回值是指针指向的当前字符,但它只是观测,指针仍停留在当前位置,并不后移。如果要访问的字符是文件结束符,则函数值是EOF(-1)。

3.putback函数
   其调用形式为
      cin.putback(ch);
   其作用是将前面用get或getline函数从输人流中读取的字符ch返回到输人流,插入到当前指针位置,以供后面读取。

例9 peek函数和putback函数的用法。
#include <iostream>
using namespace std;
int main()
 { char c[20];
   int ch;
   cout<<"please enter a sentence."<<endl;
   cin.getline(c,15,'/');
   cout<<"The first part is:"<<c<<endl;
   ch=cin.peek(); //观看当前字符
   cout<<"The next character(ASCII code) is:"<<ch<<endl;
   cin.putback(c[0]);//将'I'插入到指针所指处
   cin.getline(c,15,'/');
   cout<<"The second part is:"<<c<<endl;
   return 0; }

运行情况如下:
   please enter a sentence:
   I am a boy./I am astudent./ (回车)
   The first part is:I am a boy.
   The next chamcter(ASCII code) is:32 (下一个字符是空格)
   The second part is:I an a student

4.ignore函数

   其调用形式为: cin.ignore(n,终止字符) // 函数作用是跳过输人流中n个字符,或在遇到指定的终止字符时提前结束(此时跳过包括终止字符在内的若干字符)

如:
      ighore(5,A,) //跳过输入流中5个字符,遇A后就不再跳了
   也可以不带参数或只带一个参数。如
      ignore() (n默认值为1,终止字符默认为EOF)
   相当于:  ignore(1,EOF)

例10 用ignore函数跳过输入流中的字符。
先看不用ignore函数的情况:

#include <iostream>
using namespace std;
int main()
 { char ch[20];
   cin.get(ch,20,'/');
   cout<<"The first part is:"<<ch<<endl;
   cin.get(ch,20,'/');
   cout<<"The second part is:"<<ch<<endl;
   return 0;}

运行结果如下:
   I like C++./I study C++./I am happy.
   The first part is: I like C++
   The second part is (字符数组ch中没有从输人流中读取有效字符)

   前面已对此作过说明。如果希望第二个tin.get函数能读取”I study C++.”,就应该设法跳过输人流中第一个'/'可以用ignore函数来实现此日的,将程序改为:

#include <iostream>
using namespace std;
int main()
 { char ch[20];
   cin.get(ch,20,'/');
   cout<<"The first part is:"<<ch<<endl;
   cin.ignore(); //跳过输入流中一个字符
   cin.get(ch,20,'/');
   cout<<"The second part is:"<<ch<<endl;
   return 0; }

运行结果如下:
   I like C++./I study C++./I am happy.
   The first part is:I like C++.
   The second part is: I study C++.

以上介绍的各个成员函数,不仅可以用cln流对象来调用,而且也可以用istream类的其他流对象调用。

四、作业

1、P261:3题

2、实验八

参考:

c++输入流 无效 谷歌

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值