字符串输入输出详解

控制台I/O和文件I/O
控制台I/O是指用cin或cout将字符从控制台输入或将字符显示在控制台上
文件I/O是指用ifstream和ofstream对象将文件中中数据读入内存或将内存数据写入文件中

控制台I/O
控制台输入方式包括cin、cin.get()和cin.getline(),其中后两者是面向行输入的方法。头文件iostream中定义了istream类和ostream类,其默认对象分别为cin和cout,头文件iostream位于名称空间std中。
通常控制台输入采用istream类的默认对象cin,同时istream类提供了一些面向行的类成员函数:getline()和get()。这两个函数都读取一行输入,直到到达换行符。
cin
在用cin和>>运算符进行输入时,cin将忽略空格和换行符,因此cin>>ch将不能把空格和换行符等制表符存储在字符变量ch中,通常程序在输入时,输入的字符被缓存在缓存区中,只有用户按下回车键后缓存区中的数据才会被发送给程序,并不会在输入时及时发送给程序,所以会出现输入多于显示的字符。如

cin>>ch;
while(ch!='#')
{
    cout<<ch;
    ++count;
    cin>>ch;
}
cout<<"**"<<count<<" characters read\n";
输入:abc def ghi#jkl mn
输出:abcdefghi**9 characters read

在#号后仍然可以输入,按下回车键后输入的数据才被发送到程序,因此#后的字符不被显示,同时空格也没有被显示

面向行的输入方法
1、get()
istream类中的成员函数get()有几种形式,其中cin.get(char ch)读取输入中的下一个字符(即使是空格),并将变量赋值给ch变量。如

cin.get(ch);
while(ch!='#')
{
    cout<<ch;
    ++count;
    cin.get();
}
cout<<"**"<<count<<" characters read\n";

输入:Did you use a #2 pencil?
输出:Did you use a **14 characters read

程序显示了#号前的所有字符,包括空格,输入仍然被缓存,因此输入的字符个数比最好发送给程序的字符多

另一种输入形式为cin.get(name,size),参数解释方式和getline()类似。但是get()并不再读取并丢弃换行符,而是将其留在输入队列中,假设我们连续两次调用get()
如:

char a[20];
char b[20];
cin.get(a,20);
cin.get(b,20);
cout<<"a:"<<a<<", b:"<<b<<endl;
输入:abc def(按回车enter)
输出:a:abc def, b:

由于第一次调用后,换行符将留在输入队列中,因此第二次调用时看到的第一个字符便是换行符,因此get()认为已经到达行尾,而没有发现任何可读取的内容。如果不借助于帮助,get()将不能跨过该换行符
幸运的是,get()有另一种形式,使用不带任何参数的cin.get()调用可读取下一个字符(即使是换行符),因此可以用它来处理换行符,为读取下一行输入做好准备。可以采用下面的调用序列:

cin.get(a,20); //read first line
cin.get();   //read newline
cin.get(b,20);//read second line

还可以采用将两个类成员拼接起来的方式

cin.get(a,20).get()

之所以可以这样做,是因为cin.get(a,20)返回一个cin对象,该对象随后将被用来调用get()函数,同样,可以用下面的语句把输入中连续的两行分别读入到数组a和b中,其效果和两次调用getline()相同。

cin.getline(a,20).getline(b,20)

2、getline()
getline()函数读取整行,它使用通过回车键输入的换行符来确定输入结尾。调用这种方法,可以使用cin.getline()。该函数有两个参数,第一个参数是用来存储输入行的数组的名称,第二个参数是要读取的字符数。如果参数为20,则函数最多读取19个字符,余下的空间用于存储自动在结尾处添加的空字符。getline()成员函数在读取指定数目的字符或遇到换行符时停止读取。
例如,假如要使用getline()将姓名读入到一个包含20个元素的name数组中,可以使用这样的函数调用:

cin.getline(name,20);

这将把一行读入到name数组中——如果这行包含的字符不超过19个。

char a[20];
char b[20];

cout<<"Enter a:\n";
cin.getline(a,20);
cout<<"Enter b:\n";
cin.getline(b,20);

cout<<"a:"<<a<<", b:"<<b<<endl; 
return 0;
输入:
Enter a:
hello world
Enter b:
I love you
输出:
a:hello world, b:I love you

getline()函数每次读取一行,它通过换行符来确定行尾,但不保存换行符,在存储字符串时,它用空字符替换换行符
如:

char name[10];
cout<<"Enter your name:";
cin.getline(name,10);
输入:
Enter your name:Jud(按下回车键)

字符数组name中存储的值为”Jud\0”,getline()把换行符自动替换为空字符“\0”。

文件尾条件
如果输入来自文件,可以使用另一种更强大的技术——检测文件尾(EOF)。假设在Window系统中有一个名为read.exe的可执行程序和一个名为a.txt的文本文件,则可以在命令提示符模式下输入下面的命令

read <a

这样,程序将从文件a.txt获取输入,<符号是命令提示符模式的重定向运算符。很多PC编程环境将Ctrl+Z视为模拟的EOF,检测到EOF后,cin将两位(eofbit和failbit)都设置为1。可以通过成员函数eof()来看eofbit是否被设置,如果检测到EOF,则cin.eof()将返回false。同样,如果eofbit或failbit被设置为1,则fail()成员函数返回true,否则返回false。

猜你喜欢

转载自blog.csdn.net/gongjiwei/article/details/82585167
今日推荐