zoukankan      html  css  js  c++  java
  • 关于C++的输入输出流(cin、sstream和cout)

    测试平台g++ 5.4.0和VS2015社区版。

    输入输出原理简述

    程序的输入都建有一个缓冲区,即输入缓冲区。当一次键盘输入结束时,输入的数据会被自动存入输入缓冲区中等待处理。

    相对应的,程序的输出也建有一个缓冲区,即输出缓冲区

    cin和cout

    C++提供了两个用于处理输入和输出的预定义对象cincout,它们分别是istream类ostream类实例,这两个类是在iostream文件中定义的。

    为ostream类定义的插入操作符(<<)使得将数据插入到输出流成为可能;

    为istream类定义的提取操作符(>>)能够从输入流中提取数据。

    cin和cout都是智能对象,能够根据上下文自动将信息从一种形式转换为另一种形式

    cin对象

    cin直接从输入缓冲区中读取数据,因此,当缓冲区中有残留数据时,cin会直接取得这些残留数据而不会请求(等待)键盘输入

    同时,从标准输入流中读取数据时,cin会直接丢掉所有排在前面的空白字符(如回车符 、换行符 、制表符 、空格40等),第一个非空白符开始读取,而当读取到空白字符时则停止读取,同时丢弃该空白字符(即从输入流中删掉该字符)

    cin.get()

    •  cin.get 会保留回车符 ,第一次读取输入时停在回车符前,第二次读取输入时会直接读取该回车符,并因此停止。所以注意两次 cin.get 读取字符串间要加一个单独的 cin.get() 拿掉这个回车符
    •  cin.get(char_name) 可以用来接收字符;
    •  cin.get(char[], number) 用来接收一行字符串,可以接收空格

    cin.getline()

    • 接收一个字符串,可以接收空格并输出
    • 默认形式(回车符结束)会丢掉最后一个回车符
    • 实际上有三个参数: cin.getline(char[], number, endchar); ,分别是字符数组名,接受的字符个数,标识结束字符。其中第三个参数的系统缺省值为''(空字符,即通用的字符串结束符)。

    getline()

    • 接受一个字符串,可以接收空格并输出,需包含头文件 #include <string> 。
    • 参数列表: getline(cin, str_name, endchar); 与上一个较为不同,第一个参数表明输入流,第二个参数是接收字符串,第三个是结束字符。
    • 与 cin.getline() 的相同点是:都接收空白字符(回车符、换行符、制表符、空格等),直到结束符前停止。默认形式(回车符结束)都会丢弃掉最后一个回车符。
    •  gertline() 与 cin.getline() 的最大区别,在于它们接收变量的本质不同前者是string对象,而后者是char类型数组

    cin.sync()

    清空输入缓冲区。

    cin.ignore()

    同cin.get()一样,可读取(并丢弃)一个字符,方便读取下一个输入字符。

    测试代码(C++)

    /*三种函数都可以读取输入缓冲区的字符串数据,但是使用情况在一些细节方面会有区别
     * 下面以输入结束方式:默认enter结束和指定结束符两种情况做测试分析
     * 输入测试样例:abcd(enter)efghijk,输入结束符指定为‘i’
     * */
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        char ch1, ch2, ch3;
        char* chs1=new char;
        char* chs2=new char;
        string str;
        cout << "请输入string内容:" << endl;
        //cin.get
        //cin.get(chs1,20);    //默认形式
        cin.get(chs1,20,'i');    //指定形式
        cout << chs1 << endl; //默认形式:第一次回车即立刻输出abcd
                                             //指定形式:第二次回车立刻输出abcd(enter)efgh
        ch1=cin.get(); //默认形式:读取回车符
                              //指定形式:读取‘i’
        cout << ch1<<" "<<(int)ch1 << endl; //默认形式输出:回车符及ASCII码值10
                                                                      //指定形式输出::‘i’及ASCII码值105
        //cin.getline
        //cin.getline(chs2,20);    //默认形式
        cin.getline(chs2,20,'i');    //指定形式
        cout << chs2 << endl; //默认形式:第一次回车即立刻输出abcd
                                             //指定形式:第二次回车立刻输出abcd(enter)efgh
        ch2=cin.get(); //默认形式:第二次回车后读取第一个非空字符(第一个回车符已被丢弃)
                              //指定形式:读取‘j’(丢弃了‘i’???)
        cout << ch2<<" "<<(int)ch2 << endl; //默认形式输出:'e'及ASCII码值101
                                                                      //指定形式:‘j’及ASCII码值106
        //getline
        //getline(cin,str);    //默认形式
        getline(cin,str,'i');    //指定形式
        cout << str << endl; //默认形式:第一次回车即立刻输出abcd
                                          //指定形式:第二次回车立刻输出abcd(enter)efgh
        ch3=cin.get(); //默认形式:第二次回车后读取第一个非空字符(第一个回车符已被丢弃)
                              //指定形式:读取‘j’(丢弃了‘i’???)
        cout << ch3<<" "<<(int)ch3 << endl; //默认形式输出:'e'及ASCII码值101
                                                                      //指定形式:‘j’及ASCII码值106
        return 0;
    }

    sstream

    stringstream是C++提供的一种字符串类型的stream,和输入输出流iostream、文件流fstream有类似的操作方式。要使用stringstream,必须先加入头文件 #include <sstream> 。

    stringstream 主要用于字符串的分割,可以先用 clear() 以及 str() 将指定字符串输入字符串流中,再利用>>操作符以空白字符为界的特性将字符串分割输出,例如:

    string s;
    stringstream ss;
    int a, b, c;
    getline(cin, s);
    ss.clear();
    ss.str(s);
    ss >> a >> b >> c;

    范例

    题目描述

    输入的第一行有一个数字N,代表接下来有N行数据,每一行数据为个数不确定的整数(N最大为20,每行最大为200字节)。请写一个程序将每行的总和打印出來。

    输入:

    3
    1 2 3
    20 17 23 54 77 60
    111 222 333 444 555 666 777 888 999

    输出:

    6
    251
    4995

    代码实现(C++)

    #include <iostream>
    #include <sstream>
    using namespace std;
    
    int main() {
        string s;
        stringstream ss;
        int n, i, sum, a;
        cin >> n;
        getline(cin, s); // 读取换行
        for (i=0; i<n; i++) {
            getline(cin, s);
            ss.clear();
            ss.str(s);
            sum=0;
            while (1) {
                ss >> a;
                if (ss.fail()) break;
                sum+=a;
            }
            cout << sum << endl;
        }
        return 0;
    }

    输出部分待补充。。。

    Min是清明的茗
  • 相关阅读:
    Vue.Js(html5) + Java实现文件分片上传
    进程、线程基础知识全家桶,30 张图一套带走
    20 张图揭开「内存管理」的迷雾,瞬间豁然开朗
    面试官:换人!他连 TCP 这几个参数都不懂
    TCP 半连接队列和全连接队列满了会发生什么?又该如何应对?
    实战!我用 Wireshark 让你“看得见“ TCP
    IP 基础知识全家桶,45 张图一套带走
    写了Bug,误执行 rm -fr /*,我删删删删库了,要跑路吗?
    你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了
    硬不硬你说了算!35 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
  • 原文地址:https://www.cnblogs.com/MinPage/p/13767114.html
Copyright © 2011-2022 走看看