C++ 输入输出流总结

  • 面试中笔试常会遇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

   测试代码-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);
在这里插入代码片

猜你喜欢

转载自blog.csdn.net/u013271656/article/details/114229930