C++ C++;在eof()循环中使用迭代器进行标记化

C++ C++;在eof()循环中使用迭代器进行标记化,c++,string,iterator,C++,String,Iterator,我正在尝试调整这个答案 到我目前的字符串问题,其中涉及从一个文件读取到eof 从该源文件: Fix grammatical or spelling errors Clarify meaning without changing it Correct minor mistakes 我想创建一个包含所有标记化单词的向量。示例:vector所有文本[0]应为“修复” 我不理解istream\u迭代器end的目的但我把它包括在内,因为它在原始海报的答案上 到目前为止,我已经得到了以下非工作代码:

我正在尝试调整这个答案

到我目前的字符串问题,其中涉及从一个文件读取到eof

从该源文件:

Fix grammatical or spelling errors

Clarify meaning without changing it

Correct minor mistakes
我想创建一个包含所有标记化单词的向量。示例:v
ector所有文本[0]应为“修复”

我不理解
istream\u迭代器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?

                }
vector所有文本;
stringstream strstr;
istream_迭代器端;
istream_迭代器it(strstr);
而(!streamOfText.eof()){
getline(streamOfText,readTextLine);
CUT< P>使用< <代码>(…………)(代码)> C++中的循环被中断,因为当流进入错误状态时循环永远不会退出!

相反,您应该直接测试流的状态。根据您的代码,可以如下所示:

while (getline(streamOfText, readTextLine)) {
    cout << readTextLine << endl;
}
注意第一个参数周围的额外括号,这是从函数声明中消除歧义所必需的

编辑这段代码的一个小说明:

C++提供了一种统一的指定范围的方法。一个范围只是一个类型化值的集合,而不涉及这些值是如何存储的。在C++中,这些范围被表示为半开区间[<代码> A<代码> > >代码> B<代码>。这意味着一个范围由两个迭代器分隔。(有点像指针,但更一般;指针是一种特殊的迭代器)。第一个迭代器,

a
,指向范围的第一个元素。第二个,
b
,指向最后一个元素的后面。为什么在后面?因为这样可以很容易地在元素上进行迭代:

for (Iterator i = a; i != b; ++i)
    cout << *i;
< > >代码>值是与<代码>和值[0 ] < /代码>的同义词,这意味着它指向数组的第一个元素。<代码>值+3 < /C> >由于指针运算,几乎等同于<代码>和值[3 ] < /C>(但这是<>强>无效> /Stime> C++),指向数组后面的虚拟元素。

现在,上面的代码和前面的例子完全一样。唯一的区别是我使用的迭代器类型。我使用的是一个特殊的迭代器类,C++使用了这个迭代器类。这个迭代器类用一种方式来封装输入流,即“代码> ++/<代码>推进输入流,<代码> */Cord>读取下一个元素FR。元素的类型由类型参数指定(因此在本例中为

string

要使其作为一个范围工作,我们需要指定一个开始和一个结束。唉,我们不知道输入的结束(这是合乎逻辑的,因为当用户向控制台输入更多输入时,流的结束可能会随着时间的推移而移动!)因此,要创建虚拟结束迭代器,我们不向
istream\u iterator
的构造函数传递任何参数。相反,要创建开始迭代器,我们传递一个输入流。这将创建一个指向流中当前位置的迭代器(此处为
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);

为什么会有一个(istream_迭代器(cin)),为什么是cin?这个向量可以在不被覆盖的情况下获得XT文件的全部内容吗?我的意思是,我将从一个ifstream中读取文本文件,我想我应该将ifstream的名称放在cin所在的位置,对吗?@DminReader:cin就是一个例子-一个istream\u迭代器可以从任何istream中构造出来。@Konrad:你可能会澄清,没有参数istream_迭代器的构造函数是一种表示“从流中再也得不到什么”的方式(我忘了Josuttis是怎么说的,我知道它更好)。@DminReader:是的。
cin
只是一个例子,主要是因为它比变量名短。;-)@哈珀:我已经发布了一点解释。这让你满意吗?我毫不怀疑约瑟蒂在这方面比我做得好得多,但我只能建议大家阅读约瑟蒂的书。你应该用我的一行代码来代替你写的全部代码!正如我在回答中暗示的,循环是不必要的。
for (Iterator i = a; i != b; ++i)
    cout << *i;
int values[3] = { 1, 2, 3 };
vector<int> v(values, values + 3);
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);
string word;
while (cin >> word)
    vec.push_back(word);