stringstream 的应用总结

前言

以前没有接触过 stringstream 这个类的时候,常用的字符串和数字转换函数就是 sscanfsprintf 函数。开始的时候就觉得这两个函数应经很牛了,但是毕竟是属于 c 的。c++ 中引入了流的概念,通过流来实现字符串和数字的转换方便多了。

常见格式串

  • %% 印出百分比符号,不转换。
  • %c 整数转成对应的 ASCII 字元。
  • %d 整数转成十进位。
  • %f 倍精确度数字转成浮点数。
  • %o 整数转成八进位。
  • %s 整数转成字符串。
  • %x 整数转成小写十六进位。
  • %X 整数转成大写十六进位。
  • %n sscanf(str, "%d%n", &dig, &n)%n 表示一共转换了多少位的字符

sprintf 函数

sprintf 函数原型为 int sprintf(char *str, const char *format, ...)。作用是格式化字符串,具体功能如下所示:

(1)将数字变量转换为字符串。

(2)得到整型变量的16进制和8进制字符串。

(3)连接多个字符串。

#include <iostream>
using namespace std;
int main(){
    char str[256] = { 0 };
    int data = 1024;
    //将data转换为字符串
    sprintf(str,"%d",data);
    cout << str << endl;
    //获取data的十六进制
    sprintf(str,"0x%X",data);
    cout << str << endl;
    //获取data的八进制
    sprintf(str,"0%o",data);
    cout << str << endl;
    const char *s1 = "Hello";
    const char *s2 = "World";
    //连接字符串s1和s2
    sprintf(str,"%s %s",s1,s2);
    cout << str <<endl;
    return 0;
}

输出结果:

1024
0x400
02000
Hello World

sscanf 函数

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;
}

输出结果:123.432 432 11, 即一共转换了 11 位的字符。

stringstream 类

<sstream> 库定义了三种类:istringstreamostringstreamstringstream,分别用来进行流的输入、输出和输入输出操作。

(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清空,s.clear();

(4)实现任意类型的转换

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
    string s = "1 23 4";
    stringstream ss;
    ss << s;
    while(ss >> s){
        cout << "string: " << s << endl;
        int val = stoi(s);
        cout << "int: " << val << endl;
    }
    return 0;
}

输出:

string: 1
int: 1
string: 23
int: 23
string: 4
int: 4

例题

  1. NOIP 2007-Hanoi双塔问题

该题正解是高精度递推,但是考虑到求得都是 2 的整数幂,且最高是 \(2^{200}\),完全可以用 double 精确表示

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin >> n;
    stringstream s;
    s << fixed << setprecision(0) << pow(2, n+1);  //将pow后存进去
    string a = s.str();    //放到a中,这里个位数只能是2,4,8,6
    a[a.size()-1] -= 2;
    cout << a << endl;
    return 0;
}

所有的输出流均可以使用相同的精度控制方法,fixed 即意为取消科学计数法,配合 setprecision 函数可以设置小数部分精确到的位数。

  1. 输入一串由逗号隔开的数字
#include<bits/stdc++.h>
using namespace std;
//使用stringstream
int a[107], ct;
int main() {
	stringstream ss;
	string input;
	getline(cin, input);
	ss << input;
	string num;
	while (getline(ss, num, ','))
		a[++ct] = stoi(num);
	for (int i = 1; i <= ct; ++i)
        cout << a[i] << " ";
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[107], ct;
int main() {
	string num;
	while (getline(cin, num, ','))
		a[++ct] = stoi(num);
	for (int i = 1; i <= ct; ++i)
        cout << a[i] << " ";
	return 0;
}

输入:1,2,3,4,5

输出:1 2 3 4 5

  1. 杂项
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
	int x = 10;
	cout << showbase << uppercase;
    cout << dec << x << endl;	//输出 10
	cout << hex << x << endl;	//输出 a
	cout << oct << x << endl;	//输出 12
    cout << scientific << 1.*x << endl;
    //设置宽度,填充空白
    cout << setfill('*') << setw(12) << x << endl;
    cout << left;//设置左对齐
    cout << setfill('*') << setw(12) << x << endl;
	return 0;
}

输出结果:

10
0XA
012
1.000000E+01
*********012
012*********
posted @ 2024-04-14 11:41  飞花阁  阅读(59)  评论(0)    收藏  举报
//雪花飘落效果