and*_*and 3 c++ string iterator
我正在努力调整这个答案
到我目前的字符串问题,涉及从文件读取到eof.
来自这个源文件:
Fix grammatical or spelling errors
Clarify meaning without changing it
Correct minor mistakes
Run Code Online (Sandbox Code Playgroud)
我想创建一个包含所有标记化单词的向量.示例:vector<string> allTheText[0] should be "Fix"
我没有说明目的,istream_iterator<std::string> end;但我包括原因,这是在原始海报的答案.
到目前为止,我有这个非工作代码:
vector<string> allTheText;
stringstream strstr;
istream_iterator<std::string> end;
istream_iterator<std::string> it(strstr);
while (!streamOfText.eof()){
getline (streamOfText, readTextLine);
cout<<readTextLine<<endl;
stringstream strstr(readTextLine);
// how should I initialize the iterators it and end here?
}
Run Code Online (Sandbox Code Playgroud)
编辑:
我将代码更改为
vector<string> allTheText;
stringstream strstr;
istream_iterator<std::string> end;
istream_iterator<std::string> it(strstr);
while (getline(streamOfText, readTextLine)) {
cout << readTextLine << endl;
vector<string> vec((istream_iterator<string>(streamOfText)), istream_iterator<string>()); // generates RuntimeError
}
Run Code Online (Sandbox Code Playgroud)
并得到一个RuntimeError,为什么?
使用while (!….eof())C++中循环被打破,因为当数据流进入错误状态的循环将永远不会退出!
相反,您应该直接测试流的状态.适应您的代码,这可能如下所示:
while (getline(streamOfText, readTextLine)) {
cout << readTextLine << endl;
}
Run Code Online (Sandbox Code Playgroud)
但是,您已经有了一个流.为什么还把它放入字符串流?或者你是否需要逐行进行此操作?
您可以使用输入迭代器直接初始化矢量.无需构建字符串流,也无需使用该copy算法,因为存在适当的构造函数重载.
vector<string> vec((istream_iterator<string>(cin)), istream_iterator<string>());
Run Code Online (Sandbox Code Playgroud)
注意第一个参数周围的额外括号,这些括号是从函数声明中消除歧义所必需的.
编辑这个代码的一个小解释:
C++提供了一种指定范围的统一方法.范围只是类型值的集合,不会详细说明如何存储这些值.在C++中,这些范围表示为半开区间[ a,b[.这意味着一个范围由两个迭代器分隔(它们有点像指针但更通用;指针是一种特殊的迭代器).第一个迭代器a指向范围的第一个元素.第二,b,点后面的最后一个元素.为什么落后?因为这允许非常容易地迭代元素:
for (Iterator i = a; i != b; ++i)
cout << *i;
Run Code Online (Sandbox Code Playgroud)
与指针一样,迭代器通过应用于它们而被解除引用*.这会返回它们的值.
用C的容器类++(例如vector,list)具有一个特殊的构造,其允许值的容易复制从另一范围到新的容器中.因此,此构造函数需要两个迭代器.例如,以下将C样式数组复制到向量中:
int values[3] = { 1, 2, 3 };
vector<int> v(values, values + 3);
Run Code Online (Sandbox Code Playgroud)
在这里,它values是同义词&values[0],意味着它指向数组的第一个元素.values + 3,多亏了指针算术,几乎相当于&values[3](但这是无效的 C++!)并指向数组后面的虚拟元素.
现在,我上面的代码与上一个示例完全相同.唯一的区别是我使用的迭代器的类型.我使用C++提供的特殊迭代器类,而不是使用普通指针.此迭代器类以这样一种方式包装输入流,该方式使输入流++ 前进并*从流中读取下一个元素.元素的类型由类型参数指定(因此string在这种情况下).
要使其作为范围工作,我们需要指定开始和结束.唉,我们不知道输入的结束(这是合乎逻辑的,因为当用户向控制台输入更多输入时,流的末尾实际上可能随时间移动!).因此,要创建虚拟结束迭代器,我们不会将参数传递给构造函数istream_iterator.相反,为了创建一个begin迭代器,我们传递一个输入流.然后,这将创建一个指向流中当前位置的迭代器(此处cin).
我上面的代码在功能上等同于以下内容:
istream_iterator<string> front(cin);
istream_iterator<string> back;
vector<string> vec;
for (istream_iterator<string> i = front; i != back; ++i)
vec.push_back(*i);
Run Code Online (Sandbox Code Playgroud)
反过来,这相当于使用以下循环:
string word;
while (cin >> word)
vec.push_back(word);
Run Code Online (Sandbox Code Playgroud)