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. C#解压、压缩高级用法

    压缩:(可以吧要排除的文件去掉) /// <summary> /// 压缩文件夹 /// </summary> /// <param name="folder& ...

  2. java之struts2之拦截器

    1.struts2能完成数据的设置,数据的封装,数据的类型转换,数据的校验等等.struts2是如何来完成这些功能的?struts2的所有功能都是由拦截器来完成的. 2.拦截器是struts2的核心. ...

  3. java之struts2之类型转换

    在使用servlet开发中,表单中提交的数据到servlet后都是字符串类型,需要程序员手动进行类型转换. 但是到struts2后,基本数据类型struts2都可以转换.但是如果是自定义类型,stru ...

  4. .net core使用ocelot---第七篇 服务发现

    简介 .net core使用ocelot---第一篇 简单使用   .net core使用ocelot---第二篇 身份验证使用  .net core使用ocelot---第三篇 日志记录  .net ...

  5. 最新大型三甲医疗信息管理系统软件C#体检系统成熟PEIS源码BS架构NET网络版本

    查看体检系统演示 本源码是成熟在用大型医疗信息管理系统体检系统PEIS源码BS架构,开发语言是 asp.net c#,数据库是sqlserver2008r2,开发工具vs2010. 功能模块: 1.前 ...

  6. vue.js相关教程

    Vue.js——60分钟快速入门 http://www.cnblogs.com/keepfool/p/5619070.html

  7. csrf 功能 及 csrf装饰器使用

    目录 csrf 功能 及 csrf装饰器使用 简单了解csrf 防范措施 了解更多csrf点击 django 中 csrf csrf装饰器 csrf功能(执行流程) csrf 功能 及 csrf装饰器 ...

  8. Eclipse - servlet显示无法导入javax.servlet包问题的解决方案

    项目名-->右键 Property-->选择 Java Build Path-->选择 Add External JARs-->选择 把servlet-api.jar的路径输入 ...

  9. 阿里P7整理20个非常有用的Java程序片段,你知道吗?

    1.字符串有整型的相互转换 String a = String.valueOf(2);  //integer to numeric string   int i = Integer.parseInt( ...

  10. 微信小程序之生成图片分享 二维码分享 canvas绘制

    如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人.谢谢大家!❤ 如果解决不了,可以在文末进群交流. 添加画布 首先,在小程序里进行绘图操作需要用到<canvas>组件,步骤大致分为以 ...