#include <iostream>
#include <string>
using namespace std;
int main(int argc,char** argv)
{
const string delims(" \t,.;");
string line;
while(getline(cin,line))
{
string::size_type begIdx,endIdx;
begIdx=line.find_first_not_of(delims);
while(begIdx!=string::npos)
{
endIdx=line.find_first_of(delims,begIdx);//从begIdx开始,搜索第一个像 \t,.;的字符,即找出一个单词
if(endIdx==string::npos)//如果没找到
{
endIdx=line.length();
}
for(int i=endIdx-1;i>=static_cast<int>(begIdx);--i)/*一定要强制转化为int,因为string::size_type是一个不带正负号的整数型别,当带正负号的i与不带正负号的型别比较时,i会自动转化为无正负号值,如果目前处理的这个单词位于一行的开头,则表达式i>=begIdx永远成立,(因为begIdx为0,而任何无正负号值都大于等于0),将导致无穷循环,直到存取到某个非法地址而崩溃, */
{
cout<<line[i];
}
cout<<' ';
begIdx=line.find_first_not_of(delims,endIdx);
}
cout<<endl;
}
}
如果搜寻失败,必须返回一个特殊值来表示,该值就是npos(定义于string class中)
find_first_not_of函数返回“不隶属于参数所指字符串的第一个字符的索引
find_first_of函数用于搜寻"第一参数所指字符串内的任何字符:”的第一次出现位置,可有可无的第二参数用来标示搜寻起点,上述动作会找到单词后的第一个分隔符,如果没找到,就将endIdx设定为“行结束标记;
最后一个语句重新将begIdx初始化,使它标示下一个单词的起点(如果有下一个的话);
begIdx=line.find_first_not_of(delims,endIdx);和先前对find_first_not_of()调用的不同,这里把上一个单词的终点当做搜寻起点,如果上一个单词是该行的最后一个单词,则endIdx就是该行的终点,这意味着搜寻将从字符串终点开始,结点当然是返回string::npos
下面是测试数据:
uoy era a loof & a ekoj & tsuj rof nuf