行行宜行行

热爱风光、热爱新技术、踏出每一步,过好每一天!

stringstream与getline

在刷题过程中遇到了根据特定字符划分字符串的场景,使用到了stringstreamgetline,学习一下这种划分字符串的思路。

stringstream

stringstream字符串流,在头文件<sstream>中,本质上就是内存中的字符串流,可以像操作文件流fstream一样处理字符串,也可以支持数据的<<>>操作。

最主要的作用就是和getline配合,将字符串转换为“流”,然后按照某种规则提取片段或者分割字符串

getline

getline是属于头文件<string>中的一个函数,主要用于从输入流(cin,stringstream)中读取数据,直到遇到指定的分隔符为止,就是通过这一点特性可以用来做字符串分割

函数原型

istream& getline(istream& is, string& str, char delim);

其中:参数is表示输入流,str用来存储读取结果的字符串,delim为自定义分隔符

简单来说就是:is中读取字符串str,直到遇到了指定分隔符delim,这个分隔符会被读取但不会被存入str,并且会自动将这个字符从流中删除,或者直到末尾就结束

使用

按照leetcode71题为例,按照/拆分字符串,使用stringstreamgetline

1、初始化stringstream

需要将目标字符串(待分割的字符串)传入流,让它变成可以读取的流,例如题目中的/home//foo/

string path = "/home//foo/";
stringstring ss(path); /// 转换成字符串流

2、使用getline提取片段

分割条件是/,循环从ss中提取字串,每次得到的内容就是两个/之间的内容,题目中说多个/只保留一个,所以多个/之间提取到的字串就是空,如果为空,跳过就行

path = "/home//foo/"的拆分过程如下:

while (getline(ss, s, '/')){
   /// 处理逻辑
}
  • 第一次调用getline(ss, part, '/'): 从流的起始位置开始,遇到第一个'/'停止。此时part为空字符串(因为'/'是第一个字符,前面没有内容)。
  • 第二次调用getline(ss, part, '/'): 从第一个'/'之后开始读取,直到第二个'/'停止。读取到的内容是"home",存入part
  • 第三次调用getline(ss, part, '/'): 从第二个'/'之后开始读取,遇到第三个'/'停止。由于两个'/'之间没有字符,part为空字符串。
  • 第四次调用getline(ss, part, '/'): 从第三个'/'之后开始读取,遇到第四个'/'停止。读取到的内容是"foo",存入part
  • 第五次调用getline(ss, part, '/'): 从第四个'/'之后开始读取,到达流的末尾(没有更多字符)。part为空字符串。

3、处理一些其他的附加条件,比如空字符串(由连续'/'产生)和"."(当前目录)会被忽略,或者..会触发回退到上一级的操作(这里只需要将栈顶元素弹出就行)

主要特点

1、stringstreamgetline这个组合可以处理连续的分隔符,然后我们对拿到的字符串进行处理,如果是连续的分隔符则会读取到空字符字串。

2、这个组合保留了分割符之间的所有字符,>>运算会跳过空白字符,getline则会完整保留分隔符之间的所有字符,包括空格

3、可以自定义指定分割符(如'/'','';'等),默认是\n.

处理代码

所以这里处理字符串分割的代码示例如下:

vector<string> st;  /// 用数组模拟栈
stringstream ss(path);
string s;

// 循环读取
while (getline(ss, s, '/')) {
   if (s.empty() || s == ".")  continue;
   if (s != "..") st.push_back(s);
   else if (!st.empty()) st.pop_back();
}

// 现在st就是存放正确路径的字符串部分,再使用一个string把这些穿起来就行
Tags:
Previous Article
Next Article

发表回复

Your email address will not be published. Required fields are marked *.

*
*

近期评论

您尚未收到任何评论。

conviction

要想看到璀璨的日出时刻,就要有跋山涉水的决心和坚毅