欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

C++ 输入流

程序员文章站 2022-03-08 15:37:59
面试中笔试会遇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. 还有一种参数类型为 streambufget() 函数。
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的错误处理机制,

  • 程序执行时有一个标志变量来表示流的异常状态,如: 当到达文件的结束位置时,eofbitfailbit 都会被置位。

  • 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

相关标签: C++