- 面试中笔试常会遇
ACM模式
(需要写主函数、输入输出)。这里总结一下,方便后续查看。
概述 - iostream
<iostream>
是 Input Output Stream
的缩写,是标准的输入、输出流库。定义了标准的输入、输出对象。
Including <iostream>
还会自动包含<ios>
,<streambuf>
,<istream>
,<ostream>
和<iosfwd>
。
Note:
iostream
类主要声明在头文件<istream>
中。
输入流: std::cin
是 istream 类的对象,它主要面向窄字符(narrow characters (of type char)
)的标准输入流。
输出流: std::cout
是 ostream 类的对象,它主要面向窄字符(narrow characters (of type char)
)的标准输出流。
在理解
cin
功能时,不得不提标准输入缓冲区。当我们从键盘输入数据的时候,需要敲一下回车键才能够将这个数据送入到缓冲区
中,那么敲入的这个回车键(\r)会被转换为一个换行符(\n),这个换行符也会被存储在cin
的缓冲区中并且被当成一个字符来计算!
比如我们在键盘上敲下了 123456 这个字符串,然后敲一下回车键(\r)将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是 7 ,而不是 6。
cin
读取数据也是从缓冲区中获取数据,缓冲区为空时,cin
的成员函数会阻塞等待数据的到来,一旦缓冲区中有数据,就触发cin
的成员函数去读取数据。
1. operator>>
operator>>
应用于输入流std::cin
的运算符(operator >>
)称作提取运算符。std::cin
可以连续从键盘读取想要的数据,并忽略空格、tab 或 换行符。
I. 可通过函数
cin.fail()
判断cin
是否成功从缓冲区读取数据,若刚进行的操作失败,则返回真,否则返回假。
II. 可通过函数cin.eof() 判断 是否检测到文件尾,linux可通过Ctrl+D(window可过Ctrl+Z)模拟文件尾,当检测到 EOF后,cin.eof()
返回true
。
III. 通常使用while(cin >> a)
来进行输入,因为operator>>
函数返回对象istream&
。当读取成功时其bool
值为true
,反之为false。
IV: 因为operator>>
函数返回输入流对象istream&
,所有可以使用cin>>a>>b
来进行读取。
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;
}
输入: W // W不是int类型匹配的数据,因此读取失败,temp设置为 0
打印:int value: 0
bool(cin): 0
cin.eof : 0
cin.fail :1
输入: 100 // 读取成功,temp设置为100,
打印:int value: 100
bool(cin): 1
cin.eof : 0
cin.fail :0扫描二维码关注公众号,回复: 12640717 查看本文章
测试代码-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;
}
输入:1,2,3,4,5
打印:1 2 3 4 5
输入:1,2,3,4, ,5
输出:1 2 3 4
- 上述列子中,可以看出
cin.get()
可帮忙读取一个间隔','
字符,当连续输入两个','
字符时,cin
读取到第二个','
字符,因此bool(cin>>temp)
为 false,循环结束,导致 5 并未插入数组中。
2. get()、getline()
- 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);
-
get(char* s, streamsize n)
:参数1为数组地址,参数n
为读取的字符数,停止读取的条件如下:
(1) 读取过程中遇到换行符时,停止读取,并在该位置处将'\0'
插入数组,换行符留在输入队列中。
(2) 若 n=10 ,且输入字符串长度大于 10,则读取 9 个字符,最后一个字符自动补'\0'
。 -
get(char* s, streamsize n, char delim)
: 参数delim
为分隔符。如果找到了分隔符,则将分隔符保留在输入队列中。对于n>0,但是读取的是空字符串,也会在字符串中补一个'\0'
。
测试代码:
在这里插入代码片
istream& get (streambuf& sb); // 3. stream buffer
istream& get (streambuf& sb, char delim);
在这里插入代码片