C++输入相关的成员函数

本节我们介绍一下输入相关的常用的类成员函数。

1) get()函数

get() 函数有三种重载形式:不带参数、带一个参数和带有三个参数。首先我们来看一下不带参数的 get() 函数的使用方法。

不带参数的 get() 函数,其功能是从输入流中读入一个字符,并将其返回,但遇到文件结束符时则返回文件结束标识 EOF,文件结束符标识是采用宏定义的形式定义出来的,它的宏定义形式如下:

#define EOF (-1)


【例 1】
#include <iostream>
using namespace std;

int main()
{
    char a;
    while ( (a = cin.get()) != EOF )
    {
        cout.put(a);   
    }       
    cout << endl;
    return 0;
}
程序中借助 get() 函数,每次从输入流中读入一个字符,put() 函数都会将其输出,如此循环直到遇到文件结束符,运行结果为:(表示用户按下 Enter 换行键)

Abcdefghi 12340_+<.>?↙
Abcdefghi 12340_+<.>?↙
Asdf sss00.kkksk↙
Asdf sss00.kkksk↙
Ctrl + z

get() 函数在遇到空格、Tab 键以及换行符时,并不会像 cin 那样直接进行忽略,而是将它们当成一个字符。程序中,当用户按下 Enter 换行键之后,就会将先前输入的字符全都输出,但这并不意味着 Enter 换行键就是文件结束符,真正的原因在于,Enter 换行键会带动一次清扫缓冲区行为,每当用户按下 Enter 换行键之后都会清扫一次缓冲区,将先前输入的内容从缓冲区中读出。

文件结束符在不同的编译器上定义不同,在 Visual studio 环境中Ctrl+z就是 EOF。


带有一个参数的 get() 函数,其参数是一个 char 型变量,用于存放读入的单个字符。同时函数的返回值不再是读入的字符,而是 bool 类型,读取成功时函数返回一个非 0 值,当读取失败则返回 0,相当于 false,此时则停止读入字符。

【例 2】
#include <iostream>
using namespace std;

int main()
{
    char a;
    while ( cin.get(a) )
    {
        cout.put(a);   
    }       
    cout << endl;
    return 0;
}
运行程序

Abcdefghi 12340_+<.>?↙
Abcdefghi 12340_+<.>?↙
Asdf sss00.kkksk↙
Asdf sss00.kkksk↙
Ctrl + z


带有三个参数的 get() 函数第一个参数是字符数组或字符指针,用于将读入的字符串存入到字符数组或指针所指向的内存空间;第二个参数为读入字符个数;最后一个参数为读取的终止字符。如果未读满指定的个数就碰到了终止字符,则会提前终止读入字符。函数读取成功返回一个非 0 值,读入失败或遇到文件终止符则返回 0,即为 false。

【例 3】
#include <iostream>
using namespace std;

int main()
{
    char a[10];
    while ( cin.get( a, 10, '\n' ) )
    {
        cout << a << endl;
    }       
    cout << endl;
    return 0;
}
运行程序:

01234567890123456789↙
012345678
901234567
89

本例中使用 get() 函数依次读入字符,get() 函数的第二个参数设置为 10,但是每次读入的字符只有 9 个,这是因为字符数组末尾的一个字符为 '\0',因此每次给出的参数是 n,但每次仅读取 n-1 个字符。get() 函数的这种重载方式第三个参数可以省略,默认为 '\n'。

在系统类库中,get() 函数并非只有这三种语法格式,不过这三种使用的频繁一些,其它的重载形式可以参考 C++ 类库手册。

2) getline()函数

getline() 函数和带三个参数的 get() 函数类似,getline() 函数的三个参数与 get() 函数的三个参数含义是相同的,在此就不多做介绍了。我们直接来看下示例。

【例 4】
#include <iostream>
using namespace std;

int main()
{
    char a[10];
    cin.getline( a, 10, '7' );
    cout << a << endl;
    cin.getline( a, 10, '7' );
    cout << a << endl;
    cin.getline( a, 10 );
    cout << a << endl;
    return 0;
}
运行程序:

12345678901234567890↙
123456
890123456
890

当我们输入“12345678901234567890”时,第一次还没读取到 9 个字符就已经碰到字符 '7' 了,此时终止读入,输出 a 数组中的内容“123456”。第二次读入从‘8’开始,刚好读满9个字符,终止读入,输出 a 数组内容“890123456”。第三次读入从‘8’开始,getline() 的第三个参数默认是 '\n',因此将剩余的字符读入之后将其输出。

getline() 读取输入的字符时,终止字符是不被读入的,碰到一个终止字符就终止本次读入操作,同时指针向后移动一位,指向终止字符的后一个字符,以便下次从终止字符后面的一个字符继续读入。而带三个参数的 get() 函数碰到终止字符则停止读入,指针并不会向后移一位,下次读入的时候仍从终止字符处开始读取,如果这一次读取的终止字符与上一次读入时的终止字符相同,则本次读入将不能读到字符。这就是 getline() 函数和带三个参数的 get() 函数的差别。

3) eof()函数

eof 是 end of file 的缩写,eof() 函数可以用于判断读入数据是否遇到文件结束符,如果遇到文件结束符则返回 true,否则返回 false。

【例 5】
#include <iostream>
using namespace std;

int main()
{
    char a;
    while( ! cin.eof() )
    {
        cin.get(a);
        cout.put(a);   
    }
    return 0;
}
本程序很简单,在 while 循环每次都判断是否读入到文件结束符,如果读入文件结束符则跳出循环。

4) ignore()函数

ignore(int n, char) 函数用于忽略输入的 n 个字符或在遇到指定的字符时提前终止忽略行为。ignore() 函数的两个参数都带有默认值,n 的默认值为 1,第二个参数 char 默认值为 EOF。

【例 6】
#include <iostream>
using namespace std;

int main()
{
    char a[10];
    cin.get( a, 10, '7' );
    cout << a << endl;
    cin.ignore();
    cin.get( a, 10, '7' );
    cout << a << endl;
    cin.get( a, 10 );
    cout << a << endl;
    return 0;
}
前面我们提到过,get() 函数在第一次和第二次读入字符的时候,不会主动跳过终止字符,此时如果第一次和第二次读入的终止字符相同,用 get() 函数第二次读入则无法读入到字符,因为一开始就碰到终止字符,就终止读入了,为此我们可以使用 ignore() 函数,将这个终止字符忽略掉。忽略了终止字符后,第二次读入就不会有问题了。程序运行结果为:

12345678901234567890↙
123456
890123456
7890

因为我们使用了 ignore() 函数忽略了终止字符 '7',所以第二次依然用 '7' 作为终止字符仍然可以读取到字符。第二次读取字符完成后,并没有使用 ignore() 函数,并且第三次读入的终止字符为 '\n',因此第三次读入的字符是从 '7' 开始的。

5) peek()函数

peek() 函数没有参数,它用于返回当前指针所指的字符,并且不会移动指针。如果当前指针所指向的是文件结束符,则该函数返回 -1(EOF)。

6) putback()函数

putback(char) 函数是将 get() 或 getline() 函数读取到的字符重新插入到缓冲区当前指针所指位置,后面仍然会读取该字符。

【例 7】
#include <iostream>
using namespace std;

int main()
{
    char a[10];
    cin.get( a, 10, '7' );
    cout << a << endl;
    cin.ignore();
    cin.get( a, 10, '7' );
    cout << a << endl;
    cin.putback(a[8]);
    cin.putback(a[7]);
    cin.get( a, 10 );
    cout << a << endl;
    return 0;
}
运行程序:

12345678901234567890↙
123456
890123456
567890

在本例中,最后一次使用 get() 函数读入字符前,我们使用了两次 putback() 函数,将上一次读入的最后两个字符从新放到缓冲区中,以供第三次调用 get() 函数读入。