声明:

  • 翻译仅以技术学习和交流为目的,如需转载请务必标明原帖链接。
  • http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c

水平有限,如有翻译不当,欢迎探讨、批评与指正。

帖子内容:

C++ 切分字符串的最优雅的方式是什么?我们假定字符串中每个单词分隔符是空格。(备注:我对C的字符串函数或者那种字符处理/存取方式不是很感兴趣。因此,请优先选择优雅而不是效率)


我现在能想到的最好的方式是:

#include <iostream>
#include <sstream>
#include <string>
using namespace std; int main()
{
string s("Somewhere down the road");
istringstream iss(s); do
{
string sub;
iss >> sub;
cout << "Substring: " << sub << endl;
} while (iss); return ;
}

另一种方式去萃取输入字符串的分隔符,使用标准库函数很容易实现。下面是使用 STL 的设计方案(健壮并且优雅):

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator> int main() {
using namespace std;
string sentence = "Something in the way she moves...";
istringstream iss(sentence);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
ostream_iterator<string>(cout, "\n"));
}

如果想要把分割后的字符串放到一个容器中,而不是控制台的话,使用相同的泛型算法即可。

vector tokens;
copy(istream_iterator(iss),
istream_iterator(),
back_inserter >(tokens));[/c]

评:这种方案只能分割空格,没有伸缩性。


使用 boost 库:

std::vector strs;
boost::split(strs, "string to split", boost::is_any_of("\t "));

我打赌这个要比使用 stringstream 快的多。并且这是一个泛型模板方法,它可以用来分割任意类型的字符串(wchar,etc. or UTF-8),使用任意的分隔符。具体请看文档

评:不是每个人都用 boost 的。


把 delim 作为作为分隔符,第一个函数把结果放到一个已经存在构造好了的 vector 中,第二个函数返回一个新的 vector。

std::vector &split(const std::string &s, char delim, std::vector &elems) {
std::stringstream ss(s);
std::string item;
while(std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
} std::vector split(const std::string &s, char delim) {
std::vector elems;
return split(s, delim, elems); }

注意:这种方法不能跳过空的符号,比如下面有四个数据项,其中的一个是空的。

std::vector x = split("one:two::three", ':');
template < class ContainerT >
void tokenize(const std::string& str, ContainerT& tokens,
const std::string& delimiters = " ", const bool trimEmpty = false)
{
std::string::size_type pos, lastPos = ;
while(true)
{
pos = str.find_first_of(delimiters, lastPos);
if(pos == std::string::npos)
{
pos = str.length(); if(pos != lastPos || !trimEmpty)
tokens.push_back(ContainerT::value_type(str.data()+lastPos,
(ContainerT::value_type::size_type)pos-lastPos )); break;
}
else
{
if(pos != lastPos || !trimEmpty)
tokens.push_back(ContainerT::value_type(str.data()+lastPos,
(ContainerT::value_type::size_type)pos-lastPos ));
} lastPos = pos + ;
}
};
#include <vector>
#include <string>
#include <sstream> using namespace std; int main()
{
string str("Split me by whitespaces");
string buf; // Have a buffer string
stringstream ss(str); // Insert the string into a stream vector<string> tokens; // Create vector to hold our words while (ss >> buf)
tokens.push_back(buf); }

笔者注:

  • 文中的优雅也就是我们平时所说的代码美感。
  • 本来打算把所有的英文都翻译过来的,后来发现很多实在是难以拿捏。所以后面就直接贴了代码,其实对于我们经常看代码的人,代码也许要比文字直观的多。上文代码我在 vs2010 上验证无误。

[译]C++如何切分字符串的更多相关文章

  1. shell切分字符串到数组

    shell切分字符串到数组 问题: 对于’aa,bb,cc,dd,ee’这样的字符串输出采用,分隔开的aa bb cc dd ee aa:bb is ok:/home/work按照":&qu ...

  2. ***实用函数:PHP explode()函数用法、切分字符串,作用,将字符串打散成数组

    下面是根据explode()函数写的切分分割字符串的php函数,主要php按开始和结束截取中间数据,很实用 代码如下: <? // ### 切分字符串 #### function jb51net ...

  3. 用多个分隔符切分字符串---re.split()

    问题/需求: 需要将字符串切分,但是分隔符在整个字符串中并不一致 (即:需要用多个分隔符切分字符串) str.split()方法不可行: 只支持单一分隔符,不支持正则及多个切割符号,不感知空格的数量 ...

  4. 【译】PHP 内核 — 字符串管理

    [译]PHP 内核 - 字符串管理 (Strings management: zend_string 译文) 原文地址:http://www.phpinternalsbook.com/php7/int ...

  5. C# 如何使用长度来切分字符串

    参考网址:https://blog.csdn.net/yenange/article/details/39637211 using System; using System.Collections.G ...

  6. SQL切分字符串成int和for xml path

    切分字符 SqlServer切割字符串示例: --declare @StrDId nvarchar(2000) --set @StrDId='100,200,400,500,600' --转换ID,防 ...

  7. Python中,我该如何切分字符串后保留分割符?

    原文来源:https://stackoverflow.com/questions/2136556/in-python-how-do-i-split-a-string-and-keep-the-sepa ...

  8. c#按照指定长度切分字符串

    int pageSize=5; var array = new List<string>(); ----------方法1-------------------- var pageCoun ...

  9. Python3基础 str partition 以参数字符串切分字符串,只切分为三部分

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

随机推荐

  1. Linux操作:

    1.在Linux中第一个字符代表这个文件是目录.文件或链接文件等等. 当为[ d ]则是目录,当为[ - ]则是文件,若是[ l ]则表示为链接文档(link file),若是[ b ]则表示为装置文 ...

  2. JDK和JRE的区别?

    很多朋友可能跟我一样,已经使用JAVA开发很久了,可是对JDK,JRE,JVM这三者的联系与区别,一直都是模模糊糊的. 今天特写此文,来整理下三者的关系. JDK : Java Development ...

  3. jquery 自定义tab

    <!DOCTYPE html> <html> <head> <script src="/jquery/jquery-1.11.1.min.js&qu ...

  4. php中函数前加&符号的作用分解

    这篇文章主要介绍了php中的函数前加&符号的作用分解,其作用叫做引用返回,有点抽象,详细解释请看本文内容,需要的朋友可以参考下  (转载) php变量前面加&符号是什么意思就不用多说了 ...

  5. js字符串 数字 的转换

    js 字符串转化成数字 的 三种方法主要有 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数 ...

  6. 常用Firefox扩展

    最近思维混乱,无心做事,故整理下东西.(PS:有些是firefox自带的.) 1.标签页管理器 2.1.41 用途:在新标签页打开书签.历史.地址.搜索. 主页:http://www.firefox. ...

  7. 关于Verilog 中的for语句的探讨

    在C语言中,经常用到for循环语句,但在硬件描述语言中for语句的使用较C语言等软件描述语言有较大的区别. 在Verilog中除了在Testbench(仿真测试激励)中使用for循环语句外,在Test ...

  8. 把centos 网卡接口eth2改成eth0

    kvm 虚拟机 复制之后 默认网卡是 eth2了 用 ifconfig -a 命令查看所有的网络设置,果然没有eth0的相关设置,多出来一个eth2.显示如下:[root@neal ~]# ifcon ...

  9. start-tomcat7.launch

    <?xml version="1.0" encoding="UTF-8" standalone="no"?> <launc ...

  10. cf D. On Sum of Fractions

    http://codeforces.com/problemset/problem/397/D 题意:v(n) 表示小于等于n的最大素数,u(n)表示比n的大的第一个素数,然后求出: 思路:把分数拆分成 ...