学科分类
目录
C++基础

标准输入流

C++的istream类提供了多种形式的输入功能:istream类重载了提取运算符“>>”,使用它可以输入各种类型的数据,这是标准输入流最基本的用法;除此之外,istream还提供了成员函数get()实现字符的输入;成员函数getline()实现字符串的输入;成员函数read()实现无格式输入等,本节我们就分别来学习它们。

1、get()函数

cin是istream类的对象,它提供了从输入流中获取单个字符的成员函数get(),get()函数有三种重载形式,如下所示:

int get();
istream& get(char& ch);
istream& get(char* dst, streamsize sizechar delimiter = '\0');

下面对这三种重载形式进行详细讲解,具体如下:

● 第一种形式表示从输入流中读取一个字符,返回该字符的int值,遇到文件结束符时,返回EOF。

● 第二种形式表示从输入流中读取一个字符,存储在ch中。

● 第三种形式表示从输入流中连续读取最多size-1个字符(因为最后一个字符要留给字符’\0’),存储到首地址为dst的内存当中,delimiter是结束符,不传第三个参数,默认结束符是’\0’,也可以设置结束符是别的字符,遇到这个字符就结束读取,并且结束符不包含在所读取的字符串内。如果一直读取到size-1个字符也没有遇到结束符,则在结束读取时会自动在末尾加’\0’。

为了让读者更好的理解get()函数的用法,接下来通过一个案例来演示其用法,具体代码如例1所示。

例1

 1    #include <iostream>
 2    using namespace std;
 3    int main()
 4    {
 5        cout <<"first call: "<< cin.get() << endl;  //第一种形式调用
 6        
 7        char ch;
 8        cin.get(ch); //第二种形式调用
 9        cout <<"second call: "<< ch << endl;
 10        
 11        char str[10];
 12        cin.get(str, 8, 'T'); //第三种形式调用
 13        cout <<"third call: "<< str << endl;    
 14         system("pause");
 15        return 0;
 16    }

运行结果如图1所示。

图1 例1运行结果

在例1中,输入了“abcdeTfg”一串字符,然后分别调用get()函数的三种重载形式。第一次调用时从输入流中读取了一个字符’a’,返回的结果是其ASCII码值97;第二次调用时读取了一个字符’b’,存储到了ch变量中,所以输出ch时结果为’b’;第三次调用时从输入流中读取剩下的“cdeTfg”一串字符,但是最多只能读取8-1=7个字符存储到str数组中,结束字符标志为’T’,则在读取到’T’时结束,所以str中只有“cde”三个字符。

2、getline()函数

使用get()函数一次读取一个字符显然效率不高,对此istream类提供了另外一个函数成员getline(),它可以一次读取一个字符串,提高了读取效率,其函数声明如下的所示:

istream& getline(char* dst, streamsize size, char delimiter = ‘\n’);

它的参数意义与get()函数的第三种重载方式相同,使用方法与get()函数也类似,但是getline()函数默认结束符是’\n’,它可以读取空格、制表符等内容。接下来通过一个案例来演示getline()函数的用法,如例2所示。

例2

 1    #define _CRT_SECURE_NO_WARNINGS
 2    #include <iostream>
 3    using namespace std;
 4    int main()
 5    {
 6        int line, max = 0;
 7        char str1[100], str2[100];
 8        cout << "please input some strings:" << endl;
 9        while (cin.getline(str1, 100)) //若想结束循环,按下Ctrl+z
 10        {
 11            line = cin.gcount();  //获取getline()实际读入的字符个数
 12            if (line > max)
 13            {
 14                max = line;
 15                strcpy(str2, str1);
 16            }
 17        }
 18        cout << endl;
 19        cout << "the longest string is: " << str2 << endl;
 20        cout << "the length is: " << max << endl;
 21        system("pause");
 22        return 0;
 23    }

运行结果如图2所示。

图2 例2运行结果

在例2中,输入几个不同的字符串求其大小,并输出最长的字符串及其长度。注意:这些字符串之间有空格,也会被读取,这就是getline()与get()函数的区别:get()是一个字符一个字符的读取,而getline()是一次读取指定长度的字符串。

3、read()函数

istream类还提供了一个成员函数read(),它可以从输入流中读取部分或全部数据到指定的内存空间,其函数声明如下所示:

istream& read(char* dst, streamsize size);

read()函数参数的含义与get()、getline()函数的参数含义相同,都是读取size-1个字符存储在首地址为dst的内存空间。因为其用法也较为简单,这里就不再用案例演示,读者可以参照get()或getline()函数的用法来举例应用。

多学一招:istream类的其他成员函数

除了get()、getline()和read()函数外,istream类还提供了其他几个常用的函数。

1、ignore()函数

ignore()函数作用是跳过输入流中的n个字符,或是在遇到指定的终止符时提前结束,其函数声明如下所示:

istream& ignore(streamsize num = 1, int delim = EOF);

它从输入流中读取字符,直到已经读了num个字符(默认为1)或是直到字符delim(默认为EOF)被读入。

对于读者来说这个函数的作用可能不太容易理解,我们可以通过一个小案例来演示其作用,具体如例3所示。

例3

 1    #include<iostream>
 2    using namespace std;
 3    int main()
 4    {
 5        char str[10];
 6        cin.ignore(6, 'T'); //跳过前面6个字符,如果有T,则T终止跳跃
 7        cin.getline(str, 8);//开始读取输入的字符串,存储到str中
 8        cout << str << endl;
 9        system("pause");
 10        return 0;
 11    }

运行结果如图3所示。

图3 例3运行结果

由图3所知,str数组中是字符串”defgThi”,ignore()在读取时跳过了”abcT”四个字符,从d开始读取了8-1=7个字符。本来在调用ignore()函数时是要跳过前6个字符,但是设置了’T’为终止跳跃字符,所以它遇到’T’就停止了跳过,只跳过了前四个字符。

2、putback()函数

putback()函数声明如下所示:

istream& putback(char ch);

putback()函数是把上一次通过get()或getline()读取的字符再放回输入流中。

3、peek()函数

peek()函数的作用是观测下一个字符,其声明如下所示:

int peek();

peek()函数检查输入流中的下一个字符,它不会删除该字符,字符指针也不会移动。返回值是指针指向的当前字符。

4、gcount()函数

gcount()函数声明如下所示:

streamsize gcount();

它的作用是计算最后一个非格式化方法(get()/getline()/read()/ignore())读取到的字符数。

点击此处
隐藏目录