转载自:https://blog.csdn.net/liitdar/article/details/82598039
https://blog.csdn.net/lyj2014211626/article/details/72771320
仅作学习记录~
一、string
string 是 C++ 提供的字串型態,和 C 的字串相比,除了有不限长度的优点外,还有其他许多方便的功能。要使用 string, 必須先加入这一行:
#include
接下來要宣告一个字串变量,可以写成:
string s;
我们也可以在宣告的同时让它设成某个字串:
string s=“TCGS”;
而要取得其中某一個字元,和传统C 的字串一樣是用 s[i] 的方式取得。比较不一樣的是如果 s 有三個字元,傳統 C 的字串的 s[3] 是 0 字元,但是 C++ 的 string 則是只到 s[2] 这個字元而已。
下面我们把 string 與 字元陣列的語法做一個對照:
从上面的表格,我們可以发现 string 的用法比较直观,因此如果沒有特別的需要,尽量使用 string 會比較方便。
C和C++中字符串的区别
- string是个类,string str,是定义一个名叫str的字符串对象。
str内部保存着字符串的内容,通过str.c_str()可以获取这个字符串的首地址。
string str = “ABC”,这也不是将str赋值为"ABC"的首地址,而是使用"ABC"为值来初始化一个string类。 - 字符串的首地址是字符串中第一个字符的地址。但这些地址都是相对的地址(操作系统给的)。
char s[100] = { 0 }; s = str.c_str();
二、stringstream
概述
stringstream 是 C++ 提供的另一个字串型的串流(stream)物件,和之前学过的 iostream、fstream 有类似的操作方式。要使用 stringstream, 必須先加入這一行:
#include <sstream>
stringstream 主要是用在將一個字串分割,可以先用 clear( )以及 str( ) 將指定字串設定成一开始的內容,再用 >> 把个別的资料输出,例如:
string s;
stringstream ss;
int a, b, c;
getline(cin, s);
ss.clear();
ss.str(s);
ss >> a >> b >> c;
下面我們看到一個使用 stringstream 的例子:
題目:输入的第一行有一个数字 N 代表接下來有 N 行資料,每一行資料里有不固定個數的整數(最多 20 個,每行最大 200
個字元),請你寫一個程式將每行的总和印出來。輸入:
3
1 2 3
20 17 23 54 77 60
111 222 333 444 555 666 777 888 999輸出:
6 251 4995
程式如下:
string s;
stringstream ss;
int n, i, sum, a;
cin >> n;
getline(cin, s); // 讀取換行
for (i=0; i<n; i++)
{
getline(cin, s);
ss.clear();
ss.str(s);
sum=0;
while (1)
{
ss >> a;
if ( ss.fail() ) break;
sum+=a;
}
cout << sum << endl;
}
string类型是C语言中char *类型的一种更便利的实现。使用这个类型,不用再去刻意考虑内存的事儿。在做快速开发的时候,string对象提供的便利,还是相当出色的。然而,在这儿提醒一下:string类型很有可能成为一个工程效率问题的根源,产品级别的应用当中,应该尽量避免在深层循环嵌套中使用string类型。
除size()外,另外两个string常用的方法是find和substr。在下面的代码当中:
string str = "aaaaddddssdfsasdf";
size_t pos = str.find("ssdf", 3); //用if(pos == string::npos) 用来判断是否找到子串。
string str2 = str.substr(pos, 5);
find函数从str的第3个位置查起,找到ssdf这个子串后,返回子串的位置。而substr函数从pos位置开始,截取5个字符,赋值给str2。也就是说,str2之后的内容将是ssdfs。
stringstream是字符串流,经常被我用来作数据切分或者类型转化。一个经常被我用到的函数如下:
string i2s(int i, int len = 0)
{
stringstream ss;
ss << setw(len) << setfill('0') << i;
return ss.str():
}
以i2s(7, 3)形式调用这个函数,返回的结果是字符串007。我通常在循环里,这样产生或者遍历一些文件。
为什么使用stringstream
如果你已习惯了<stdio.h>风格的转换,也许你首先会问:为什么要花额外的精力来学习基于的类型转换呢?也许对下面一个简单的例子的回顾能够说服你。假设你想用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()后包含了一个不确定的字符串。要是能自动推导出正确的类型,那不是更好吗?
由于n和s的类型在编译期就确定了,所以编译器拥有足够的信息来判断需要哪些转换。库中声明的标准类就利用了这一点,自动选择所必需的转换。而且,转换结果保存在stringstream对象的内部缓冲中。你不必担心缓冲区溢出,因为这些对象会根据需要自动分配存储空间。
代码示例
1.数据类型转换
这里展示一份示例代码,介绍将 int 类型转换为 string 类型的过程。
示例代码(stringstream_test1.cpp)的内容如下:
#include <string>
#include <sstream>
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
stringstream sstream;
string strResult;
int nValue = 1000;
// 将int类型的值放入输入流中
sstream << nValue;
// 从sstream中抽取前面插入的int类型的值,赋给string类型
sstream >> strResult;
cout << "[cout]strResult is: " << strResult << endl;
printf("[printf]strResult is: %s\n", strResult.c_str());
return 0;
}
编译并执行上述代码,结果如下:
2. 多个字符串拼接
本示例介绍在 stringstream 中存放多个字符串,实现多个字符串拼接的目的(其实完全可以使用 string 类实现),同时,介绍 stringstream 类的清空方法。
示例代码(stringstream_test2.cpp)的内容如下:
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringstream sstream;
// 将多个字符串放入 sstream 中
sstream << "first" << " " << "string,";
sstream << " second string";
cout << "strResult is: " << sstream.str() << endl;
// 清空 sstream
sstream.str("");
sstream << "third string";
cout << "After clear, strResult is: " << sstream.str() << endl;
return 0;
}
编译并执行上述代码,结果如下:
从上述代码执行结果能够知道:
- 可以使用 str() 方法,将 stringstream 类型转换为 string 类型;
- 可以将多个字符串放入 stringstream中,实现字符串的拼接目的;
- 如果想清空 stringstream,必须使用 sstream.str(""); 方式;clear() 方法适用于进行多次数据类型转换的场景。详见示例 3。
3. tringstream的清空
清空 stringstream 有两种方法:clear() 方法以及 str("") 方法,这两种方法对应不同的使用场景。str("") 方法的使用场景,在上面的示例中已经介绍过了,这里介绍 clear() 方法的使用场景。
示例代码(stringstream_test3.cpp)的内容如下:
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringstream sstream;
int first, second;
// 插入字符串
sstream << "456";
// 转换为int类型
sstream >> first;
cout << first << endl;
// 在进行多次类型转换前,必须先运行clear()
sstream.clear();
// 插入bool值
sstream << true;
// 转换为int类型
sstream >> second;
cout << second << endl;
return 0;
}
编译并执行上述代码,结果如下:
注意:在本示例涉及的场景下(多次数据类型转换),必须使用 clear() 方法清空 stringstream,不使用 clear() 方法 或 使用 str("") 方法,都不能得到数据类型转换的正确结果。下图分别是未使用 clear() 方法、使用 str("") 方法代替 clear() 方法时的运行结果: