您的位置:首页 > 编程语言 > C语言/C++

c++中stringstream 类的用法及字符串与数字之间转化

2017-08-23 18:45 387 查看
iostream标准库支持对于内存的输入输出,只要将流与存储在程序内存中的string对象捆绑在一起,就可以使用通用的输入输出操作符来读写string对象!标准库中定义了三种类型的字符串流:
istringstream,由istream派生出来的,用于读一个string的对象;
ostringstream,由ostream派生出来的,用于写一个string的对象;
stringstream,由iostream派生出来,同时提供了对于stringstream对象的功能!!
要是用上述的三个类,必须包含sstream头文件!!
stringstream对象的一个重要的功能是让我们更方便的操作string对象!

1.stringstream::str(); returns a string object with a copy of the current contents of the stream.

 2.stringstream::str (const string& s); sets s as the contents of the stream, discarding any previous contents.

  3.stringstream清空,stringstream s; s.str("");

  4.实现任意类型的转换

    template<typename out_type, typename in_value>

    out_type convert(const in_value & t){

    stringstream stream;

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

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

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

   return result;


例子:可以在定义这个对象的时候进行初始化操作:

#include<sstream>

#include<string>

#include<iostream>

using namespace std;

int main()

{

            string str;

            int i = 12345;

            stringstream ss;

            ss << i;

            str = ss.str();

            return 0;

}

其中ss.str()返回的是一个流中保存的string对象的副本,这样就实现了通过流对象对一个string对象的赋值操作从而增加string对象操作的灵活性!
2、另外一个很重要的方面就是可以通过stringstream来实现数据类型的转换将一个string对象中保存的字符串
还原成原来的数据结构!
#include<sstream>
#include<string>
#include<iostream>
using namespace std;
int main()
{
            string str = “12345true”;
            stringstream ss;
            int i;
            bool j;
            ss.str(str);
            ss >> i;
            ss >> j;
            cout << i <<endl;
            cout << j <<endl;
            return 0;
}
3、另外一个非常重要是将其作为一个socket通信中一个重要的载体来接收和存储recv和send处理的数据!
这样就可以直接作为boost序列化和反序列化的操作对象,来实现序列化和反序列化的操作!
while(true)
{
          if((x = recv(int socket,char *buf, int len,0)) < 0)
           {
                        sys_err("recv() error!!");
                        exit(-1);
            }
           else if(x > 0)//说明此处的数据尚未接收完毕,继续往流对象中添加!!
           {
                      ss << buf;
 
       }
            else
            {
                          break;
             }
}
boost::archive::text_iarchive ia(ss);
ia >> BOOST_SERIALIZATION_NVP(des);//这样就可以直接将接受的数据对象进行反序列化操作,在
内存中进行,提高了速度!!这里对于des目标类的序列化操作具体课参加这篇文中的内容!http://www.linuxidc.com/Linux/2012-08/69192.htm
send(int socket,char *buf,int len,0);
对于发送的操作同样可以直接利用我们这里stringstream对象:
boost::archive::text_oarchive oa(ss);
oa << BOOST_SERIALIZATION_NVP(des);通过这样的方式将我们需要发送的数据结构写入流对象!
send(socket,ss.str(),ss.str().size(),0);将流中存储的序列化之后的字符串,直接发送出去,加快了速度!

4、在类型转换中使用模板

你可以轻松地定义函数模板来将一个任意的类型转换到特定的目标类型。例如,需要将各种数字值,如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++的streanstream:


#include <sstream>


#Include <string>


string num2str(double i)


{


        stringstream ss;


        ss<<i;


        return ss.str();


}

字符串转数字:


int str2num(string s)


 {   


        int num;


        stringstream ss(s);


        ss>>num;


        return num;


}
对比之前的sprintf和scanf函数:

sprintf函数原型为 int sprintf(char *str, const char *format, ...)。作用是格式化字符串,具体功能如下所示:
  (1)将数字变量转换为字符串。
  (2)得到整型变量的16进制和8进制字符串。
  (3)连接多个字符串。
int main(){
char str[256] = { 0 };
int data = 1024;
//将data转换为字符串
sprintf(str,"%d",data);
//获取data的十六进制
sprintf(str,"0x%X",data);
//获取data的八进制
sprintf(str,"0%o",data);
const char *s1 = "Hello";
const char *s2 = "World";
//连接字符串s1和s2
sprintf(str,"%s %s",s1,s2);
cout<<str<<endl;
return 0;
}

 sscanf函数原型为int sscanf(const char *str, const char *format, ...)。将参数str的字符串根据参数format字符串来转换并格式化数据,转换后的结果存于对应的参数内。具体功能如下:
  (1)根据格式从字符串中提取数据。如从字符串中取出整数、浮点数和字符串等。
  (2)取指定长度的字符串
  (3)取到指定字符为止的字符串
  (4)取仅包含指定字符集的字符串
  (5)取到指定字符集为止的字符串
  当然,sscanf可以支持格式串"%[]"形式的,有兴趣的可以研究一下。
int main(){
char s[15] = "123.432,432";
int n;
double f1;
int f2;
sscanf(s, "%lf,%d%n", &f1, &f2, &n);
cout<<f1<<" "<<f2<<" "<<n;
return 0;
} 输出:1 1 23 23 # 0 4 4
常见的格式串:
%% 印出百分比符号,不转换。
  %c 整数转成对应的 ASCII 字元。
  %d 整数转成十进位。
  %f 倍精确度数字转成浮点数。
  %o 整数转成八进位。
  %s 整数转成字符串。
  %x 整数转成小写十六进位。
  %X 整数转成大写十六进位。
  %n sscanf(str, "%d%n", &dig, &n),%n表示一共转换了多少位的字符
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: