原文地址:http://blog.163.com/zhuandi_h/blog/static/180270288201291710222975/

GDC注:今天在做《C++ Primer中文版第四版》第10章的练习——文本查询程序,因为涉及到将字符串分为单词,所以特意写了一个字符串类来处理这件事。做完后,看了作者的源码,发现他是利用istringstream类来实现的,看起来很简洁。因为之前没研究过这个类的原理及使用,于是在该书中的第8.5小节找到了该类的一些介绍,到此才算对字符串流有了了解。有了了解就得总结,发博客,但是俺实在太懒,就到网上搜一下相关文章,找到这篇还算不错的文章,特此转载,以备以后复习之用。(当然了,这个类也是有一些局限的,因为它只能根据空白符进行分词,而我做的类则可以根据用户指定的分词字符进行分词)

使用stringstream对象简化类型转换
C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能,即单纯性、类型安全和可扩展性。在本文中,我将展示怎样使用这些库来实现安全和自动的类型转换。

为什么要学习

如果你已习惯了<stdio.h>风格的转换,也许你首先会问:为什么要花额外的精力来学习基于<sstream>的类型转换呢?也许对下面一个简单的例子的回顾能够说服你。假设你想用sprintf()函数将一个变量从int类型转换到字符串类型。为了正确地完成这个任务,你必须确保证目标缓冲区有足够大空间以容纳转换完的字符串。此外,还必须使用正确的格式化符。如果使用了不正确的格式化符,会导致非预知的后果。下面是一个例子:

int n=10000;

chars[10];

sprintf(s,”%d”,n);// s中的内容为“10000”

到目前为止看起来还不错。但是,对上面代码的一个微小的改变就会使程序崩溃:

int n=10000;

char s[10];

sprintf(s,”%f”,n);// 看!错误的格式化符

在这种情况下,程序员错误地使用了%f格式化符来替代了%d。因此,s在调用完sprintf()后包含了一个不确定的字符串。要是能自动推导出正确的类型,那不是更好吗?

进入stringstream

由于n和s的类型在编译期就确定了,所以编译器拥有足够的信息来判断需要哪些转换。<sstream>库中声明的标准类就利用了这一点,自动选择所必需的转换。而且,转换结果保存在stringstream对象的内部缓冲中。你不必担心缓冲区溢出,因为这些对象会根据需要自动分配存储空间。

你的编译器支持<sstream>吗?

<sstream>库是最近才被列入C++标准的。(不要把<sstream>与标准发布前被删掉的<strstream>弄混了。)因此,老一点的编译器,如GCC2.95,并不支持它。如果你恰好正在使用这样的编译器而又想使用<sstream>的话,就要先对它进行升级更新。

<sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本。简单起见,我主要以stringstream为中心,因为每个转换都要涉及到输入和输出操作。

注意,<sstream>使用string对象来代替字符数组。这样可以避免缓冲区溢出的危险。而且,传入参数和目标对象的类型被自动推导出来,即使使用了不正确的格式化符也没有危险。

string到int的转换

string result=”10000”;
int n=0;
stream<<result;
stream>>n;//n等于10000

重复利用stringstream对象

如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法;

在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。

在类型转换中使用模板

你可以轻松地定义函数模板来将一个任意的类型转换到特定的目标类型。例如,需要将各种数字值,如int、long、double等等转换成字符串,要使用以一个string类型和一个任意值t为参数的to_string()函数。to_string()函数将t转换为字符串并写入result中。使用str()成员函数来获取流内部缓冲的一份拷贝:

template<class T>

void to_string(string & result,const T& t)

{

ostringstream oss;//创建一个流

oss<<t;//把值传递如流中

result=oss.str();//获取转换后的字符转并将其写入result
}

这样,你就可以轻松地将多种数值转换成字符串了:

to_string(s1,10.5);//double到string

to_string(s2,123);//int到string

to_string(s3,true);//bool到string

可以更进一步定义一个通用的转换模板,用于任意类型之间的转换。函数模板convert()含有两个模板参数out_type和in_value,功能是将in_value值转换成out_type类型:

template<class out_type,class in_value>

out_type convert(const in_value & t)

{

stringstream stream;

stream<<t;//向流中传值

out_type result;//这里存储转换结果

stream>>result;//向result中写入值

return result;

}

这样使用convert():

double d;

string salary;

string s=”12.56”;

d=convert<double>(s);//d等于12.56

salary=convert<string>(9000.0);//salary等于”9000”

结论

在过去留下来的程序代码和纯粹的C程序中,传统的<stdio.h>形式的转换伴随了我们很长的一段时间。但是,如文中所述,基于stringstream的转换拥有类型安全和不会溢出这样抢眼的特性,使我们有充足得理由抛弃<stdio.h>而使用<sstream>。<sstream>库还提供了另外一个特性—可扩展性。你可以通过重载来支持自定义类型间的转换。

一些实例:

stringstream通常是用来做数据转换的。

相比c库的转换,它更加安全,自动和直接。

例子一:基本数据类型转换例子 int转string

# include <string>
# include <sstream>
# include <iostream>

int main()
{
    std::stringstream stream;
    std:: string result;
    int i = 1000;
    stream << i;  // 将int输入流
    stream >> result;  // 从stream中抽取前面插入的int值
    std::cout << result << std::endl;  //  print the string "1000"
}

运行结果:

例子二:除了基本类型的转换,也支持char *的转换。

# include <sstream>
# include <iostream>

int main()
{
    std::stringstream stream;
    char result[8] ;
    stream << 8888;  // 向stream中插入8888
    stream >> result;  // 抽取stream中的值到result
    std::cout << result << std::endl;  //  屏幕显示 "8888"
}

例子三:再进行多次转换的时候,必须调用stringstream的成员函数clear().

# include <sstream>
# include <iostream>
int main()
{
    std::stringstream stream;
    int first, second;
    stream<< "456";  // 插入字符串
    stream >> first;  // 转换成int
    std::cout << first << std::endl;
    stream.clear();  // 在进行多次转换前,必须清除stream
    stream <<  true;  // 插入bool值
    stream >> second;  // 提取出int
    std::cout << second << std::endl;

运行clear的结果

没有运行clear的结果

注:关于stream.clear()和stream.str(""),作用还不太清楚。又说clear是清除标志位,str("")是清楚stream内容的。但在多次转换过程是,的确是使用clear才准确,这是验证过的。

c++ 字符串流 sstream(常用于格式转换)相关推荐

  1. c++ 字符串流 sstream

    c++ 字符串流 sstream 文章目录 c++ 字符串流 sstream 1.0**重复利用stringstream对象** 1.1 例题 2.0 **stringstream的用法总结** 2. ...

  2. 【Hive】常用日期格式转换和计算

    文章目录 格式转换 字符串 方法一:substr + concat 方法二: from_unixtime+ unix_timestamp 时间戳或者日期 方法一:date_format(time_va ...

  3. 《Python程序设计》python常用的格式转换

    #字典 tinydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} tinydict['Age'] = 8 # 更新 tinydict['Schoo ...

  4. 【SQLServer】常用时间格式转换

    目录 1.语法 2.日期和时间样式 3.使用 CONVERT 处理不同格式的 datetime 数据 4.测试 5.参考链接 1.语法 CONVERT Syntax: CONVERT ( data_t ...

  5. Hive常用日期格式转换

    固定日期转换成时间戳 select unix_timestamp('2016-08-16','yyyy-MM-dd') --1471276800 select unix_timestamp('2016 ...

  6. android 常用时间格式转换代码

    /**   * 获取现在时间   *    * @return 返回时间类型 yyyy-MM-dd HH:mm:ss   */ public static Date getNowDate() {   ...

  7. Sql Server datetime 常用日期格式转换

    我们经常出于某种目的需要使用各种各样的日期格式,当然我们可以使用字符串操作来构造各种日期格式,但是有现成的函数为什么不用呢? SQL Server中文版的默认的日期字段datetime格式是yyyy- ...

  8. 常用视频格式转换nv12,i420,i444,p010

    文章目录 视频存储格式 NV12转I420 NV12转I444 P010转I420 视频存储格式 P010格式与NV12格式一样,区别就是两个字节存一个像素值. Y Y Y Y Y Y Y Y Y Y ...

  9. C++中的字符串流详解iostream,sstream

    注:本文只详解C++中的#include <iostream> ,#include <sstream>,暂不详解#include <fstream>.等后期博主会补 ...

最新文章

  1. Error in **** : non-numeric argument to binary operator
  2. 地图样式自定义_干货在线 | ArcGIS中定义图框样式
  3. 中文输入法不触发onkeyup事件的解决办法
  4. swig模板 PHP,nodejs前端模板引擎swig入门
  5. vb.net限制datagridview不能选择_家里安装200兆宽带,网速还是很慢怎么办?教你一招解除网速限制...
  6. 用workbench给表重命名_MySQL Workbench的使用方法(图文)
  7. Part5 数据的共享与保护 5.4类的友元5.5共享数据的保护
  8. jQuery 中json字符串与对象互转
  9. C++/C--STL API查询及免费教程网站
  10. android 应用切换滑动,Android应用中利用ViewPager实现多页面滑动切换效果示例
  11. DPDK 16.04/16.11.2 默认tx offload是关闭的引起tx vlan offload无效
  12. 期刊论文格式模板 电子版_期刊论文发表流程是怎样的呢?
  13. Java实现Unicode和中文相互转换
  14. typedef用法,函数指针
  15. PV、UV、IV的概念
  16. springCloud微服务生态圈囊括—— 服务注册,服务调用,服务降级,熔断。(1)
  17. H5+CSS3+JS/JQ 实现京东首页
  18. 如何将英文pdf文档在线翻译成中文?
  19. jquery mobile外部js无法载入问题
  20. 泰迪云课堂数据分析案例:广电大数据营销推荐项目

热门文章

  1. linux如何批量操作,linux批量操作命令锦集
  2. JNLP文件详细说明
  3. JSONPath(XPath for JSON)解析 JSON教程
  4. 踩坑:云服务器Nginx部署前端遇到http与https问题
  5. apollo新增扩展consul注册中心
  6. SDN(软件定义网络)基本概念
  7. linux md文件 编辑,用Vim写md文档的简单姿势
  8. 网络爬虫是干什么的呢?
  9. firefox(火狐浏览器)插件的应用
  10. 数据挖掘和大数据分析