输出一行字符串,根据空白符来分隔单词。先看如何输出一行(带空白)
int main()
{
string s;
//read and split each line of input
while(getline(cin,s))
{
vector<string> v=split(s);
for(vector<string.;:size_type i=0;i!=v.size();i++)
cout<<v[i]<<endl;
}
}
如何写split函数呢? 首先常规的思维如下:
vector<string> split(const string& s)
{
vector<string> ret;
typedef string::size_type string_size;
string_size i = 0;
// invariant: we have processed characters `['original value of `i', `i)'
while (i != s.size()) {
// ignore leading blanks
// invariant: characters in range `['original `i', current `i)' are all spaces
while (i != s.size() && isspace(s[i]))
++i;
// find end of next word
string_size j = i;
// invariant: none of the characters in range `['original `j', current `j)' is a space
while (j != s.size() && !isspace(s[j]))//j!=s.size()很容易忽略
++j;
// if we found some nonwhitespace characters
if (i != j) {
// copy from `s' starting at `i' and taking `j' `\-' `i' chars
ret.push_back(s.substr(i, j - i));
i = j;
}
}
return ret;
}
isspace在cctype头文件中。这个程序有很多值得注意的地方。
while (i != s.size() && isspace(s[i])) ++i;
&&有短路特性。先判断左边的是否为真,若为假就不会判断后面的了。首先必须先检查i!=s.size();只有当这个检测为真时,才可以使用i来查看s中的一个字符是否为空白符。
若使用标准库算法,更接近人的思维。
// `true' if the argument is whitespace, `false' otherwise
bool space(char c)
{
return isspace(c);
}
// `false' if the argument is whitespace, `true' otherwise
bool not_space(char c)
{
return !isspace(c);
}
vector<string> split(const string& str)
{
typedef string::const_iterator iter;
vector<string> ret;
iter i = str.begin();
while (i != str.end()) {
// ignore leading blanks
i = find_if(i, str.end(), not_space);
// find end of next word
iter j = find_if(i, str.end(), space);
// copy the characters in `[i,' `j)'
if (i != str.end())
ret.push_back(string(i, j));
i = j;
}
return ret;
}
这个程序也有很多值得注意的地方。首先,
ret.push_back(string(i, j)); 不能写成 ret.push_back(str.substr(i,j));因为c++不能将迭代器转换成整形。外层循环有了一个i!=str.end()的判断,里面为什么还有有i!=str.end()的判断?是因为字符串末尾可能有很多空白符。如“abc "; 但最后一次j赋值给i时。i指向第一个空白符,i!=str.end()为true,i继续找,最终指向了str.end(), 而j=find_if(str.end(),str.end(),space);还有特别要注意的是:函数形参中 const string& str; str.begin()if the conatiner is a const object ,返回的迭代器类型是const_iterator在定义迭代时typedef string::const_iterator iter;若形参不写const,string& str;
typedef string::const_iterator iter;
则find_if函数模板调用出错,错误信息:模板 参数“_InIt”不明确原因,find_if里面的迭代器是iterator类型,返回的也是iterator类型,而直接赋值给了const_iterator是不行的。
原文链接: https://www.cnblogs.com/youxin/archive/2012/05/15/2502323.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/50341
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!