C++的iostream标准库介绍(2)

  接下来我们继续看一下C++风格的串流控制,C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含sstream.h头文件。

istringstream类用于执行C++风格的串流的输入操作。
  stringstream类同时可以支持C++风格的串流的输入输出操作。

  strstream类同时可以支持C风格的串流的输入输出操作。

  istringstream类是从istream(输入流类)和stringstreambase(c++字符串流基类)派生而来,ostringstream是从ostream(输出流类)和stringstreambase(c++字符串流基类)派生而来,stringstream则是从iostream(输入输出流类)和和stringstreambase(c++字符串流基类)派生而来。

  他们的继承关系如下图所示:

  istringstream是由一个string对象构造而来,istringstream类从一个string对象读取字符。

  istringstream的构造函数原形如下:
  istringstream::istringstream(string str);

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
#include <iostream> 
#include <sstream> 
using namespace std; 
int main()  

istringstream istr; 

istr.str("1 56.7",); 
//上述两个过程可以简单写成 istringstream istr("1 56.7"); 
cout << istr.str()<<endl; 
int a; 
float b; 

istr>>a; 
cout<<a<<endl; 

istr>>b; 
cout<<b<<endl; 

system("pause"); 
}

  上例中,构造字符串流的时候,空格会成为字符串参数的内部分界,例子中对a,b对象的输入"赋值"操作证明了这一点,字符串的空格成为了整型数据与浮点型数据的分解点,利用分界获取的方法我们事实上完成了字符串到整型对象与浮点型对象的拆分转换过程。

  str()成员函数的使用可以让istringstream对象返回一个string字符串(例如本例中的输出操作(cout<<istr.str();)。

  ostringstream同样是由一个string对象构造而来,ostringstream类向一个string插入字符。

  ostringstream的构造函数原形如下:
  ostringstream::ostringstream(string str);

  示例代码如下:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
#include <iostream> 
#include <sstream> 
#include <string> 
using namespace std; 
int main()  

ostringstream ostr; 
//ostr.str("abc");//如果构造的时候设置了字符串参数,那么增长操作的时候不会从结尾开始增加,而是修改原有数据,超出的部分增长 

ostr.put('d'); 
ostr.put('e'); 
ostr<<"fg"; 
 
string gstr = ostr.str(); 
cout<<gstr; 
system("pause"); 
}

  在上例代码中,我们通过put()或者左移操作符可以不断向ostr插入单个字符或者是字符串,通过str()函数返回增长过后的完整字符串数据,但值得注意的一点是,当构造的时候对象内已经存在字符串数据的时候,那么增长操作的时候不会从结尾开始增加,而是修改原有数据,超出的部分增长。

  对于stringstream了来说,不用我多说,大家也已经知道它是用于C++风格的字符串的输入输出的。

  stringstream的构造函数原形如下:

  stringstream::stringstream(string
str);

  示例代码如下:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
#include <iostream> 
#include <sstream> 
#include <string> 
using namespace std; 
 
int main()  

    stringstream ostr("ccc"); 

    ostr.put('d'); 
    ostr.put('e'); 
    ostr<<"fg"; 

    string gstr = ostr.str(); 
    cout<<gstr<<endl; 
 
    char a; 
    ostr>>a; 
    cout<<a 
     
    system("pause"); 
}

  除此而外,stringstream类的对象我们还常用它进行string与各种内置类型数据之间的转换。

  示例代码如下:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
#include <iostream> 
#include <sstream> 
#include <string> 
using namespace std; 
 
int main()  

    stringstream sstr; 
//--------int转string----------- 
    int a=100; 
    string str; 

    sstr<<a; 
    sstr>>str; 
    cout<<str<<endl; 
//--------string转char[]-------- 
    sstr.clear();//如果你想通过使用同一stringstream对象实现多种类型的转换,请注意在每一次转换之后都必须调用clear()成员函数。 

    string name = "colinguan"; 
    char cname[200]; 
    sstr<<name; 

    sstr>>cname; 
    cout<<cname; 
    system("pause"); 
}

  接下来我们来学习一下输入/输出的状态标志的相关知识,C++中负责的输入/输出的系统包括了关于每一个输入/输出操作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是一个枚举类型(就像open_mode一样),以下便是它包含的值。

goodbit 无错误

Eofbit 已到达文件尾

failbit 非致命的输入/输出错误,可挽回

badbit 致命的输入/输出错误,无法挽回

  有两种方法可以获得输入/输出的状态信息。一种方法是通过调用rdstate()函数,它将返回当前状态的错误标记。例如,假如没有任何错误,则rdstate()会返回goodbit.

  下例示例,表示出了rdstate()的用法:

//程序作者:管宁   
//站点:www.cndev-lab.com   
//所有稿件均有版权,如要转载,请务必著名出处和作者   
 
#include <iostream> 
using namespace std; 
 
int main()  

    int a; 

    cin>>a; 
    cout<<cin.rdstate()<<endl; 
    if(cin.rdstate() == ios::goodbit) 
    { 
        cout<<"输入数据的类型正确,无错误!"<<endl; 
    } 

    if(cin.rdstate() == ios_base::failbit) 
    { 

        cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl; 

    } 
    system("pause"); 
}

  另一种方法则是使用下面任何一个函数来检测相应的输入/输出状态:

bool bad();

bool eof();

bool fail();

bool good();

  下例示例,表示出了上面各成员函数的用法:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
 
#include <iostream> 
using namespace std; 
 
int main()  

    int a; 

    cin>>a; 
    cout<<cin.rdstate()<<endl; 
    if(cin.good()) 
    { 

        cout<<"输入数据的类型正确,无错误!"<<endl; 

    } 
    if(cin.fail()) 
    { 
        cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl; 

    } 
    system("pause"); 
}

  如果错误发生,那么流状态既被标记为错误,你必须清除这些错误状态,以使你的程序能正确适当地继续运行。要清除错误状态,需使用clear()函数。此函数带一个参数,它是你将要设为当前状态的标志值。,只要将ios::goodbit作为实参。

  示例代码如下:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
 
#include <iostream> 
using namespace std; 
 
int main()  

    int a; 

    cin>>a; 
    cout<<cin.rdstate()<<endl; 
    cin.clear(ios::goodbit); 

    cout<<cin.rdstate()<<endl; 
    system("pause"); 

}

  通常当我们发现输入有错又需要改正的时候,使用clear()更改标记为正确后,同时也需要使用get()成员函数清除输入缓冲区,以达到重复输入的目的。

  示例代码如下:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
#include <iostream> 
using namespace std; 
 
int main()  

    int a; 

    while(1) 
    { 
        cin>>a; 
        if(!cin)//条件可改写为cin.fail() 

        { 
            cout<<"输入有错!请重新输入"<<endl; 
            cin.clear(); 
            cin.get(); 
        } 
        else 
        { 
            cout<<a; 
            break; 
        } 
    } 
    system("pause"); 

}

  最后再给出一个对文件流错误标记处理的例子,巩固学习,代码如下:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
#include <iostream> 
#include <fstream> 
using namespace std; 
 
int main()  


    ifstream myfile("c:\\1.txt",ios_base::in,0); 
    if(myfile.fail()) 
    { 
        cout<<"文件读取失败或指定文件不存在!"<<endl; 
    } 

    else 
    { 
        char ch; 
        while(myfile.get(ch)) 
        { 
            cout<<ch; 
        } 
        if(myfile.eof()) 
        { 
            cout<<"文件内容已经全部读完"<<endl; 
        } 

        while(myfile.get(ch)) 
        { 

            cout<<ch; 
        } 

    } 
    system("pause"); 
}

 
 

《挑战30天C++入门极限》C++的iostream标准库介绍(2)的更多相关文章

  1. 《挑战30天C++入门极限》引言

    作为一个长篇的C++入门教程,无论如何也应该有这么个引言,可是文笔并不好的我,想了很久也不知道该如何写...... 仔细想想,与其把这篇短文当作教程的引言,其实它更应该是一篇引导初学者步入C++殿堂的 ...

  2. 《挑战30天C++入门极限》入门教程:实例详解C++友元

        入门教程:实例详解C++友元 在说明什么是友元之前,我们先说明一下为什么需要友元与友元的缺点: 通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为pu ...

  3. 《挑战30天C++入门极限》C++面向对象编程入门:构造函数与析构函数

        C++面向对象编程入门:构造函数与析构函数 请注意,这一节内容是c++的重点,要特别注意! 我们先说一下什么是构造函数. 上一个教程我们简单说了关于类的一些基本内容,对于类对象成员的初始化我们 ...

  4. 《挑战30天C++入门极限》C++类静态数据成员与类静态成员函数

        C++类静态数据成员与类静态成员函数 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? ...

  5. 《挑战30天C++入门极限》C++类对象的复制-拷贝构造函数

        C++类对象的复制-拷贝构造函数 在学习这一章内容前我们已经学习过了类的构造函数和析构函数的相关知识,对于普通类型的对象来说,他们之间的复制是很简单的,例如: int a = 10; int ...

  6. 《挑战30天C++入门极限》C++面向对象编程入门:类(class)

        C++面向对象编程入门:类(class) 上两篇内容我们着重说了结构体相关知识的操作. 以后的内容我们将逐步完全以c++作为主体了,这也意味着我们的教程正式进入面向对象的编程了. 前面的教程我 ...

  7. 《挑战30天C++入门极限》新手入门:C/C++中的结构体

        新手入门:C/C++中的结构体 什么是结构体? 简单的来说,结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构 ...

  8. 《挑战30天C++入门极限》新手入门:C++中堆内存(heap)的概念和操作方法

        新手入门:C++中堆内存(heap)的概念和操作方法 堆内存是什么呢? 我们知道在c/c++中定义的数组大小必需要事先定义好,他们通常是分配在静态内存空间或者是在栈内存空间内的,但是在实际工作 ...

  9. 《挑战30天C++入门极限》新手入门:C++中的函数重载

        新手入门:C++中的函数重载 函数重载是用来iostream>  using namespace std;  int test(int a,int b);  float test(flo ...

  10. 《挑战30天C++入门极限》新手入门:关于C++中的内联函数(inline)

        新手入门:关于C++中的内联函数(inline) 在c++中,为了解决一些频繁调用的小函数大量消耗栈空间或者是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数. 可能说到这里,很 ...

随机推荐

  1. 未检测到.NET CORE SDK 或者 新建项目没有.NET CORE 3.0选择项

    终于解决了 首先先看自己的VS2019版本 由于楼主下载的 .NET CORE SDK 3.0.100-preview8-013656 焕然大悟 原来是版本不符合,需要用vs 2019 preview ...

  2. webpack-dev-server的使用

    1.安装 npm install webpack-dev-server --save-dev ps:为保证webpack-dev-server能正常运行,请确认在本地项目中下载了webpack的包,可 ...

  3. HTML学习摘要3

    DAY 3 浏览器会自动地在标题的前后添加空行 默认情况下,HTML 会自动地在块级元素前后添加一个额外的空行,比如段落.标题元素前后. <hr /> 标签在 HTML 页面中创建水平线. ...

  4. webpack---eslint-loader学习随笔

    第一步.在项目内安装: npm i -D eslint eslint-loader . 第二步.webpack的配置loader 注意loader的顺序,需先执行eslint-loader. 第三步. ...

  5. python selenium八大定位方法

    一.定位方法 注意:元素属性必须唯一存在 #id定位 find_element_by_id() #name定位 find_element_by_name() #class_name定位 find_el ...

  6. Tomcat启动超时设置

    Tomcat启动超时设置: 处理方法: 1. 在server中找到当前Tomcat双击. 2.在视图中进行修改.(如下图:)

  7. vscode 上安装 leetcode插件

    vscode 真是一款非常好的轻量级的代码编辑工具,无论windows还是ubuntu使用体验都非常好. leetcode用来练练脑子吧,不要老年痴呆了. 1. 安装vscode Ubuntu先去下载 ...

  8. Kotlin泛型与协变及逆变原理剖析

    在上一次https://www.cnblogs.com/webor2006/p/11234941.html中学习了数据类[data class]相关的知识,这次会学习关于泛型相关的东东,其中有关于泛型 ...

  9. vue项目中要实现展示markdown文件[转载]

    转载 版权声明:本文为CSDN博主「齐天二圣」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/nihaoa5 ...

  10. Shell排序——软考(五)

    希尔排序是一种插入排序,是对直接插入排序的一种改进,该算法出自于D.L.Shell,因此得名为希尔.Shell排序又名缩小增量排序. 思想      假设初始序列为n个元素,先取一个小于n的整数d1作 ...