1.stringstream

一.概述

<sstream> 定义了三个类:istringstreamostringstreamstringstream,分别用来进行流的输入、输出和输入输出操作。
<sstream> 主要用来进行数据类型转换,由于 <sstream> 使用 string 对象来代替字符数组(snprintf方式),就避免缓冲区溢出的危险;而且,因为传入参数和目标对象的类型会被自动推导出来,所以不存在错误的格式化符的问题。简单说,相比c库的数据类型转换而言,<sstream> 更加安全、自动和直接。

二.应用

(1)数据类型的转换

将 int 类型转换为 string 类型

#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
    stringstream ss;
    string s;
    int n=666;
    ss<<n;//把int型的n流进去(放入输入流中)

    ss>>s;//把前面进来的int型变成string型再流出来
    cout<<s<<endl;
    return 0;
}

输出:

666

(2)用于长句子中空格为界分割单词

UVA10815 安迪的第一个字典 Andy’s First Dictionary

题意翻译
输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出,单词不区分大小写。

#include<bits/stdc++.h>
using namespace std;
set<string>se;
int main()
{
    string s,buf;
    while(cin>>s)
    {
        for(int i=0;i<s.length();i++)
        {
            if(isalpha(s[i]))s[i]=tolower(s[i]);
            else s[i]=' ';
        }
        stringstream ss(s);
        while(ss>>buf)
           se.insert(buf);
    }
    set<string>::iterator it;
    for(it=se.begin();it!=se.end();it++)
            cout<<*it<<endl;
    return 0;
}

(3)stringstream的清空(ss.clear();ss.str("");的区别)

清空 stringstream 有两种方法:clear() 方法以及 str("") 方法,这两种方法有不同的使用场景。一但ss流出去了再想调用就一定要用clear()清空,如果没有流出去就可以用str("")清空
下面的代码可以注释一行感受一下我上面说的str和clear的使用场景会有更深刻的印象

#include <sstream>
#include <iostream>
using namespace std;
int main()
{
    stringstream ss;
    int first,second;string third;

    // 插入字符串
    ss<<"666";
    // 转换为int类型
    ss>>first;
    cout<<first<<endl;
    
    ss.clear();
    
    // 插入bool值
    ss<<true;
    ss>>second;
    cout<<second<<endl;
    
    ss.clear();//流出去过了所以必须用clear
    ss.str("");//再用str("")把之前ss中的字符串清空
    ss<<"123456"<<" "<<"77777";
    ss<<" 99999";

    cout<<ss.str()<<endl;
    return 0;
}


输出:

666
1
123456 77777 99999

如果最后一个clear没有写的话就会输出这个:

666
1

三.C++中stringstream的使用方法和样例(转)

istringstream是由一个string对象构造而来,从一个string对象读取字符。
ostringstream同样是有一个string对象构造而来,向一个string对象插入字符。
stringstream则是用于C++风格的字符串的输入输出的。

代码测试:

#include<iostream>
#include <sstream> 
using namespace std;<pre name="code" class="cpp">int main(){
	string test = "-123 9.87 welcome to, 989, test!";
	istringstream iss;//istringstream提供读 string 的功能
	iss.str(test);//将 string 类型的 test 复制给 iss,返回 void 
	string s;
	cout << "按照空格读取字符串:" << endl;
	while (iss >> s){
		cout << s << endl;//按空格读取string
	}
	cout << "*********************" << endl;
 
	istringstream strm(test); 
	//创建存储 test 的副本的 stringstream 对象
	int i;
	float f;
	char c;
	char buff[1024];
 
	strm >> i;
	cout <<"读取int类型:"<< i << endl;
	strm >> f;
	cout <<"读取float类型:"<<f << endl;
	strm >> c;
	cout <<"读取char类型:"<< c << endl;
	strm >> buff;
	cout <<"读取buffer类型:"<< buff << endl;
	strm.ignore(100, ',');
	int j;
	strm >> j;
	cout <<"忽略‘,’读取int类型:"<< j << endl;
 
	system("pause");
	return 0;
}

输出:


总结:

1)在istringstream类中,构造字符串流时,空格会成为字符串参数的内部分界;
2)istringstream类可以用作string与各种类型的转换途径
3)ignore函数参数:需要读取字符串的最大长度,需要忽略的字符

代码测试:

int main(){
	ostringstream out;
	out.put('t');//插入字符
	out.put('e');
	out << "st";
	string res = out.str();//提取字符串;
	cout << res << endl;
	system("pause");
	return 0;
}

输出:test
注:如果一开始初始化ostringstream,例如ostringstream out("test"),那么之后put或者<<时的字符串会覆盖原来的字符,超过的部分在原始基础上增加。

stringstream同理,三类都可以用来字符串和不同类型转换。
这两段话和两段代码转自这里

2.itoa函数与atoi函数

一.概述

1.int/float to string/array:

C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明。

itoa():将整型值转换为字符串。
● ltoa():将长整型值转换为字符串。
● ultoa():将无符号长整型值转换为字符串。
● gcvt():将浮点型数转换为字符串,取四舍五入。
● ecvt():将双精度浮点型值转换为字符串,转换结果中不包含十进制小数点。
● fcvt():指定位数为转换精度,其余同ecvt()

除此外,还可以使用sprintf系列函数把数字转换成字符串,其比itoa()系列函数运行速度慢

2. string/array to int/float
C/C++语言提供了几个标准库函数,可以将字符串转换为任意类型(整型、长整型、浮点型等)。

atof():将字符串转换为双精度浮点型值。
● atoi():将字符串转换为整型值。
● atol():将字符串转换为长整型值。
● strtod():将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字。
● strtol():将字符串转换为长整值,并报告不能被转换的所有剩余数字。
● strtoul():将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字。
# include <stdio.h>
# include <stdlib.h>
void main (void)
{
int num = 100;
char str[25];
itoa(num, str, 10);
printf("The number 'num' is %d and the string 'str' is %s. \n" ,
num, str);
}

itoa()函数有3个参数:第一个参数是要转换的数字,第二个参数是要写入转换结果的目标字符串,第三个参数是转移数字时所用 的基数。在上例中,转换基数为10。10:十进制;2:二进制…
所以

二.itoa函数—将整型值转换为字符串

(1)可以用itoa函数将10进制数转换成二进制数并用字符串输出

蓝桥杯01字符串
问题描述
对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:

00000
00001
00010
00011
00100

请按从小到大的顺序输出这32种01串。
输入格式
本试题没有输入。
输出格式
输出32行,按从小到大的顺序每行一个长度为5的01串。
样例输出

00000
00001
00010
00011

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+7;
const ll mod=2147483647;
int main()
{
    for(int i=0;i<32;++i)
    {
        char s[100];
        itoa(i,s,2);
        ll len=strlen(s);
        if(len<5)
            for(int i=0;i<5-len;++i)
                cout<<0;
        printf("%s\n",s);
    }
    return 0;
}

itoa并不是一个标准的C函数,它是Windows特有的,如果要写跨平台的程序,请用sprintf。是Windows平台下扩展的,标准库中有sprintf,功能比这个更强,用法跟printf类似:

char str[255];
sprintf(str, "%x", 100); //将100转为16进制表示的字符串。

三.atoi函数—把字符串转换成整型数

C++版

#include <iostream>
using namespace std;
int str2int(const char *str)
{
    int temp = 0;
    const char *ptr = str;  //ptr保存str字符串开头
    if (*str == '-' || *str == '+')  //如果第一个字符是正负号,
    {                      //则移到下一个字符
        str++;
    }
    while(*str != 0)
    {
        if ((*str < '0') || (*str > '9'))  //如果当前字符不是数字
        {                       //则退出循环
            break;
        }
        temp = temp * 10 + (*str - '0'); //如果当前字符是数字则计算数值
        str++;      //移到下一个字符
    }
    if (*ptr == '-')     //如果字符串是以“-”开头,则转换成其相反数
    {
        temp = -temp;
    }

    return temp;
}
int main()
{
    int n = 0;
    char p[10] = "";

    cin.getline(p, 20);   //从终端获取一个字符串
    n = str2int(p);      //把字符串转换成整型数

    cout << n << endl;

    return 0;
}

3.对比

其实没什么好对比的,个人习惯了
itoa和atoi必须用字符数组来接收,而且atoi 只能接收Int型,都有严格的限制,容易出bug,没有string stream好用,string stream是用string接收,string它不香嘛,所以有C++ 的高科技为什么要用c风格的落后函数呢,stringstream真香