[译]C++如何切分字符串

声明:

  • 翻译仅以技术学习和交流为目的,如需转载请务必标明原帖链接。
  • 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 0;
}

另一种方式去萃取输入字符串的分隔符,使用标准库函数很容易实现。下面是使用 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 = 0;
   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 + 1;
   }
};
#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 上验证无误。
时间: 2024-10-30 09:06:32

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

使用正则表达式--切分字符串

转自廖老师的课程: 用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码: 'a b c'.split(' '); // ['a', 'b', '', '', 'c'] 嗯,无法识别连续的空格,用正则表达式试试: 'a b c'.split(/\s+/); // ['a', 'b', 'c'] 无论多少个空格都可以正常分割.加入,试试: 'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd'] 再加入;试试: 'a,b;; c d'.sp

shell切分字符串到数组

shell切分字符串到数组 问题: 对于’aa,bb,cc,dd,ee’这样的字符串输出采用,分隔开的aa bb cc dd ee aa:bb is ok:/home/work按照":"分割开来的aa      bb is ok      /home/work 解决方法1: #!/bin/bash var=’aa,bb,cc,dd,ee’ var=${var//,/ } #这里是将var中的,替换为空格 for element in $var do echo $element done

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

镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.------------------------------------------ code: myStr='hello WORLD hello WORLD' print(myStr) myNewStr=myStr.partition(' ') #空格仍在新的元组里面,而且你可以看到只切分为三部分 print(myNewStr) result: =============

OC习题 -- 切分字符串 处理色值和名称 (知识点: 字典,枚举,数组,字符串)

/* 处理工程文件crayons.txt中的文本信息,文本内容是关于颜色的,每行都是一 个颜色的信息,例如:Almond #EED9C4,前?一个字符串是颜色的名称,后一 个字符串是颜?色的16进制色值,处理?文本完成如下需求: 1.使用字典管理所有的颜色,即字典中存储的是多个键值对,颜?色名称为 key,16进制颜色值(不带#)是value. 2.取出所有的key,升序排列. 3.取出所有的value,按照排序后的key排列. 4.使?用一个新的字典管理颜色,对颜色进?行分类管理,即:“A”,

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

(Strings management: zend_string 译文) 原文地址:http://www.phpinternalsbook.com/php7/internal_types/strings/zend_strings.html 原文仓库:https://github.com/phpinternalsbook/PHP-Internals-Book 原文作者:phpinternalsbook 译文出自:https://github.com/suhanyujie 本文永久链接: 译者:su

如何用多个字符串来切分字符串

string str="我是小松鼠hsgg()jsjg776sdf"; string [] sArray=Regex.Split(str,"[hs][()]",RegexOptions.IgnoreCase); int i =1; foreach (string s in sArray) { Console.WriteLine("i,{0},len:{1},s:{2}",I++,s.length,s); } Console.WriteLine(&

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

? python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 conda : 4.5.11 type setting : Markdown ? code [email protected]:~$ source activate py37 (py37) [email protected]:~$ ipython Python 3.7.0 (default, Jun 28 2018, 13:15:42) Type 'copyright'

jstl fortokens 分割字符串

forTokens标签: forTokens标签用来截取字符串: 属性: * var :定义变量 * items :切分字符串 * begin :从哪开始 * end :到哪结束 * step :步长 * varStatus :记录循环变量 * delims :按照什么字符切分 代码: <c:forTokens var="s" items="aaa,bbb,ccc,ddd" delims=","> ${ s }<br/>

python字符串操作分类总结

1.切片操作: str[start:end:step]包括头,不包括尾巴step为步长,意思是每隔step-1个元素,取一个字符"while"[::-1] 反向取字符串,实现字符串的反转-->"elihw" 2.方法:字符串的修饰:center: 让字符串在指定的长度居中,如果不能居中,左短右长 "while".center(10) --> while "while".center(10, 'a')-->aa