C++ 输入流
程序员文章站
2022-06-23 08:10:16
面试中笔试会遇ACM模式(需要写主函数、输入输出)。因此这里总结一下几个输入函数,方便后续查看。 1. iostream 1. iostream...
1. cin
<iostream>
是 Input Output Stream
的缩写,是标准的输入、输出流库。定义了标准的输入、输出对象。
Including <iostream>
还会自动包含<ios>
,<streambuf>
,<istream>
,<ostream>
和<iosfwd>
。
输入流: std::cin
是 istream 类的对象,它主要面向窄字符(narrow characters (of type char)
)的标准输入流。
输出流: std::cout
是 ostream 类的对象,它主要面向窄字符(narrow characters (of type char)
)的标准输出流。
- I.
std::cin
可以连续从键盘读取想要的数据,并忽略空格、tab 或 换行符。 - II. 可通过函数
cin.fail()
判断cin
是否成功从缓冲区读取数据,若刚进行的操作失败,则返回真,否则返回假。 - III. 可通过函数
cin.eof()
判断 是否检测到文件尾,linux可通过Ctrl+D(window可过Ctrl+Z)模拟文件尾,当检测到 EOF后,cin.eof()
返回true
。
1.1 operator>>
-
operator>>
应用于输入流std::cin
的运算符(operator >>
)称作提取运算符。
-
operator >>
函数原型如下:
istream& operator>> (bool& val); // arithmetic types (1)
istream& operator>> (short& val); // >> 右侧为缓冲区数据:
istream& operator>> (unsigned short& val);
istream& operator>> (int& val)
... // 此处省略其他同类型函数
istream& operator>> (streambuf* sb ); // stream buffers (2)
istream& operator>> (istream& (*pf)(istream&)); // manipulators (3)
istream& operator>> (ios& (*pf)(ios&));
istream& operator>> (ios_base& (*pf)(ios_base&));
测试代码-1:
int main () {
int tmp = 999;
cin >> tmp;
cout << "int value: " << tmp
<< " \nbool(cin): " << bool(cin)
<< " \ncin.eof : " << cin.eof()
<< " \ncin.fail : " << cin.fail() << endl;
return 0;
}
测试代码-2:
int main () {
vector<int> data;
int tmp;
while (cin >> tmp){ // 读取数据,将数据插入 vector中
data.push_back(tmp);
if (cin.get() == '\n') // cin.get()读取 ','
break;
}
for (auto& i:data) // 打印 vector
cout << i << " ";
return 0;
}
-
cin >> temp
会读取一个匹配类型,并将后续数据留在输入缓冲区中。 - 上述列子中,可以看出
cin.get()
可帮忙读取一个间隔','
字符,当连续输入两个','
字符时,cin
读取到第二个','
字符,因此bool(cin>>temp)
为 false,循环结束,导致 5 并未插入数组中。
1.2 get()
- get() 有多种重载形式:
- I.
get()
或get(ch)
可读取缓冲区的下一个字符,哪怕是空格或回车,因此可以使用它来读取分隔符。
int get();
istream& get(char& c);
测试代码-1:
int main () {
vector<int> data;
int tmp;
char ch;
cin.get(ch);
cin >> tmp;
cout << ch << tmp; // 即使 ch 为空格或回车,都会打印ch
return 0;
}
- II. 下述原型函数中,函数
get()
从缓冲区读取字符串并将其存储在 C 风格的字符串中。
istream& get(char* s, streamsize n);
istream& get(char* s, streamsize n, char delim);
测试代码-2:
// istream& get(char* s, streamsize n);
int main() {
char ch;
char array[20];
cin.get(array,20);
cin.get(ch);
cout << array << " " << int(ch) << endl;
return 0;
}
测试代码-3:
// istream& get(char* s, streamsize n, char delim);
int main() {
char ch;
char array[20];
cin.get(array,20,'A'); // 使用分隔符,遇到‘A’停止,‘A’留在输入缓冲中
cin.get(ch);
cout << array << " " << int(ch) << endl;
return 0;
}
- III. 还有一种参数类型为
streambuf
的get()
函数。
istream& get(streambuf& sb); // 3. stream buffer
istream& get(streambuf& sb, char delim);
1.3 getline()
- 从函数名可以看出,该函数读取一行数据。
-
getline()
函数与get()
功能相似,不同在于当遇到换行符时,getline()
将丢弃换行符,而get()
将换行符保留在输入缓冲中。
istream& getline(istream& is, string& str);
istream& getline(istream& is, string& str, char delim);
int main() {
char name[20];
cin.getline(name,20); // 1. 舍弃换行符
char age[10];
cin.getline(age,20,'A'); // 2. 分隔符‘A’
char ch;
cin.get(ch);
cout << "name: " << name;
cout << " age: " << age;
cout << " ch: " << int(ch);
return 0;
}
- 可以看出,读取名称
fufu
后,舍弃了换行符。 - 继续读取
13!A
时,遇到分隔符'A'
,丢弃'A'
,此时输入缓冲区还剩下换行符。 -
cin.get(ch)
读取换行符,打印出来对应的int为10
.
1.4 cin 的条件状态
-
最开始时简单的讲解了
cin.fail()
和cin.eof()
。这些函数都是与cin的错误处理有关的
。这一节我们来分析一下cin的错误处理机制, -
程序执行时有一个标志变量来表示流的异常状态,如: 当到达文件的结束位置时,
eofbit
和failbit
都会被置位。 -
I/O流
有四种条件状态,用三位标志位来控制:状态名称-----------标志位--------状态含义 ios::goodbit 000 流状态正常 ios::badbit 001 输入(输出流)出现致命错误,无法挽回 ios::eofbit 010 已到达文件尾 ios::failbit 100 输入(输出流)出现错误,可挽回
int main() {
cout << ios::goodbit << endl;
cout << ios::badbit << endl;
cout << ios::eofbit << endl;
cout << ios::failbit << endl;
return 0;
}
-
状态条件对应功能
cin.eof() eofbit 被置位时,该函数返回 true cin.fail() failbit 被置位时,该函数返回 true cin.bad() badbit 被置位时,该函数返回 true,表示当前正常 cin.good() goodbit 被置位时,该函数返回 true cin.clear(flags) 清空状态标志位,并将给定的标志位flags置为1,返回void。 cin.rdstate() 返回流的当前状态,返回int类型的上述4种 状态 cin.setstate(flags) 不清空当前状态,设置给定的状态 flags,返回 void
int main() {
char str[20];
int tmp = 999;
cout << "good,bad,eof,fail: " << cin.good() << " "
<< cin.bad() << " "
<< cin.eof() << " "
<< cin.fail() << endl; // 查看错误状态
cin.getline(str, 5); // 1. 读取4个字符
cout << "good,bad,eof,fail: " << cin.good() << " "
<< cin.bad() << " "
<< cin.eof() << " "
<< cin.fail() << endl;
cin.clear(); // 2. 清除输入流对象cin的异常状态
cout << "good,bad,eof,fail: " << cin.good() << " "
<< cin.bad() << " "
<< cin.eof() << " "
<< cin.fail() << endl;
cin >> tmp; // 3. A 写入 int类型tmp, fail
cout << "good,bad,eof,fail: " << cin.good() << " "
<< cin.bad() << " "
<< cin.eof() << " "
<< cin.fail() << endl;
cin.clear(); // 4. 清除fail
cin >> tmp;
cout << "tmp:" << tmp << endl; // 5. 在次将缓冲区的数据写入int类型,错误
// 因为前面 3.的读取失败,使得 'A' 留在了缓冲区
cin.clear();
cin.get(); // 6. get() 读取 'A'
cin >> tmp; // 7. 正确写入
cout << "str:" << str << endl;
cout << "tmp:" << tmp << endl;
return 0;
}
2. std::getline()
- 头文件
#include<string>
中包含getline()方法如下:
istream& getline(istream& is, string& str, char delim); // 1.
istream& getline(istream& is, string& str); // 2.
-
getline()
利用istream
可以从标准输入设备键盘读取一行,当遇到如下几种情况会结束读操作:
(1)文件结束,或发生其他错误。
(2)遇到行分隔符,结束读取,分隔符被丢弃(输入缓存中的数据是分隔符的下一个)
int main()
{
string str;
getline(cin, str); // 1. 读取下面的输入: fufufu
string str_tmp;
getline(cin, str_tmp, 'A'); // 2. 读取输入:loveU, 舍弃'A',缓冲区为 1和换行
char ch;
cin.get(ch); // 3. 读取1
cout << str_tmp << "###" << str << "###" << ch << endl;
return 0;
}
本文地址:https://blog.csdn.net/u013271656/article/details/114229930