C++输入输出

用来读取命令行输入的几个函数与区别

cin

cin是如何确定已完成字符串输入的呢?我们知道,不能通过键盘输入空字符。因此cin使用空白(空格、制表符和换行符)来确定字符串结束的位置。cin会忽略空格和换行符,制表符。
同时发送给cin的输入将被缓冲,这意味着只有用户在按下回车键之后,缓冲区的内容才会发送给程序。

每次读取一行的字符串输入

istream 中的类如cin 提供了一些面向行的类成员函数:getline()get 这两个函数都读取一行的输入,直到到达换行符,它们的区别是,getline() 会将换行符丢弃,而get()会将换行符保留在输入队列中。

  • istream::getline()
//函数原型
istream& getline (char* s, streamsize n ); //原型1
istream& getline (char* s, streamsize n, char delim ); //原型2

getline() 函数读取整行,通过回车键输入的换行符来确定输入结尾。要调用这种方法,可使用cin.getline()。该函数原型1有两个接受两个参数。第一个参数用来接受存储 输入行的数组名称,第二个参数是要读取的字符数n。该函数最多接受n-1个字符,剩余位置用来存储'\0' 。注意这里接受的参数类型是char*

char name[10];
cout<<"Enter your name:";
cin.getline(name,10);
//用户输入"jack",然后按下回车。

cin.getline()读取用户输入和键入Enter键生成的换行符,并将换行符替换为'\0'

int get();
istream& get (char& c);	
istream& get (char* s, streamsize n); //常用
istream& get (char* s, streamsize n, char delim);//边界字符
istream& get (streambuf& sb);
istream& get (streambuf& sb, char delim);

由函数原型知道,该函数有很多变体。我们在这里只讨论和istream::getline() 工作方式类似的一种。他们接受的参数相同,且都是读取到行尾。get()不丢弃换行符,而是将其留在输入队列中。这会导致一下问题的产生:

char name[10];
char address[20];
cin.get(name,10);
cin.get(address,10); //此处会产生问题

第一此调用函数产生的换行符会保留在输入队列中,一次第二次调用接受的第一个字符就是换行符,此时该函数认为已经到达行尾,发现没有任何需要读取的内容。这时注意到上述原型第一个不接受任何参数的get() ,它可读取下一个字符(即使是换行符)。因此可用它来处理换行符。即:

char name[10];
char address[20];
cin.get(name,10);
cin.get(); //读取换行符
cin.get(address,10);

或者

cin.get(name,10).get();

之所以这样做,是因为该函数调用会返回一个cin对象,可以继续调用istream::get()函数。类似的istream::getlin()函数也一样,具体可见函数原型。
可以用istream::get()判断停止读取的原因是什么。如果是换行符,则说明读取了整行,否则后续还有输入。

需要注意的问题

  • istream::getline()或者istream::get()读取空行会发生什么?
    istream::get()读取空行后将设置failbit使接下来的输入被阻断,可用cin.clear()来恢复。
  • 当输入的字符串比分配的空间长时
    istream::get()istream::getline()会将余下的字符留在输入队列中,而且istream::getline()还会设置失效位failbit并关闭后面的输入。
  • 混合输入字符串和数字
    混合输入字符串和数字可能会产生问题
int num;
cin>>num;
char str[80];
cin.getline(str,80);

在种种情况下,用户会没有输入str的机会,因为cin读取年份生成的换行符留在输入队列中。此时后面的cin.getline()看到换行符后,认为是一个空行,并将一个空字符赋给str数组。解决的方法是在cin>>num之后加入cin.get()。即

int num;
cin>>num;
cin.get();
char str[80];
cin.getline(str,80);
int num;
(cin>>num).get();
char str[80];
cin.getline(str,80);
  • stringI/O
    可以使用cin和运算符>>来将输入对象存储到string对象中,使用cout和运算符<<显示。但当每次读取一行而不是一个单词时,string类的处理方法稍有不同。
string str;
getline(cin,str);

这里的getline()不是类方法,它将cin作为参数,指出到哪里去寻找输入,此外string对象会根据字符串大小自动调整自己的大小。

讨论循环和文本输入

cin对象支持3种不同模式的单字符输入,其用户接口各不相。

  • 使用原始的cin进行输入
    通常使用哨兵字符(sentinel character),缺点不能将空白字符读入(空白字符就是isspace()返回true的对象。
#include<iostream>
int main()
{
	using namespace std;
	char ch;
	int count = 0;
	cout<<"输入字符,按#结束\n";
	cin>>ch;
	while(ch!='#')
	{
		cout<<ch;
		++count;
		cin>>ch;
	}
	cout<<endl<<count<<" 字符被读取\n";
	return 0;
}

代码测试
程序会忽略空白字符。

  • 使用cin.get()
#include<iostream>
int main()
{
	using namespace std;
	char ch;
	int count = 0;
	cout<<"输入字符,按#结束\n";
	cin.get(ch);
	while(ch!='#')
	{
		cout<<ch;
		++count;
		cin.get(ch);
	}
	cout<<endl<<count<<"个字符被读取\n";
	return 0;
}

在这里插入图片描述
cin.get()会读取空白字符,输入仍然被缓冲。

  • 文件尾条件EOF
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值