我想在一个字符串的字段上进行迭代。
这个字符串可以被认为是由空格分隔的单词组成的。
请注意,我对C语言的字符串函数或那种字符操作/访问不感兴趣。另外,请在你的答案中优先考虑优雅性而不是效率。
我现在的最佳解决方案是。
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string s = "Somewhere down the road";
istringstream iss(s);
do
{
string subs;
iss >> subs;
cout << "Substring: " << subs << endl;
} while (iss);
}
有没有更优雅的方法呢?
STL已经没有这样的方法了。
然而,你可以使用C'的strtok()
函数,通过使用std::string:c_str()
成员,或者你可以自己编写。下面是我在谷歌快速搜索后发现的一个代码样本("STL字符串分割")。
void Tokenize(const string& str,
vector<string>& tokens,
const string& delimiters = " ")
{
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
摘自:<http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html>。
如果你对代码样本有疑问,请留下评论,我会解释。
仅仅因为它没有实现一个叫做迭代器的typedef
或重载<<
操作符,并不意味着它是坏的代码。我经常使用C函数。例如,printf
和scanf
都比std::cin
和std::cout
快(明显),fopen
的语法对二进制类型更友好,而且它们也倾向于产生更小的EXE。
不要被这种"优雅高于性能"的交易所迷惑。
使用std::stringstream
就像你所做的那样,工作得非常好,而且完全是你想要的。如果你只是在寻找不同的方法,你可以使用std::find()
/std::find_first_of()
和std::string::substr()
。
这里有一个例子。
#include <iostream>
#include <string>
int main()
{
std::string s("Somewhere down the road");
std::string::size_type prev_pos = 0, pos = 0;
while( (pos = s.find(' ', pos)) != std::string::npos )
{
std::string substring( s.substr(prev_pos, pos-prev_pos) );
std::cout << substring << '\n';
prev_pos = ++pos;
}
std::string substring( s.substr(prev_pos, pos-prev_pos) ); // Last word
std::cout << substring << '\n';
return 0;
}