正如其他人已经指出的那样(例如参见herohuyongtao's answer),必须修复循环条件以及如何将str1 放入istringstream。
然而,这里有一个到目前为止大家都忽略的重要问题:你根本不需要istringstream!
vec.reserve(the_number_of_words_you_exptect_at_least);
while (infile >> str1) {
vec.push_back(str1);
}
它摆脱了您最初不需要的内部循环,并且不会在每次迭代中创建istringstream。
如果您需要进一步解析每一行并且确实需要istringstream,请在循环之外创建它,并通过istringstream::str(const string& s) 设置其字符串缓冲区。
我可以很容易地想象您的循环非常慢:Windows 上的堆分配非常慢(与 Linux 相比);我被咬过一次。
Andrei Alexandrescu 在他的演讲 Writing Quick Code in C++, Quickly 中提出(在某种意义上)一个类似的例子。令人惊讶的是,像上述那样在紧密循环中进行不必要的堆分配可能比实际的文件 IO 慢。我很惊讶地看到这一点。
您没有将您的问题标记为 C++11,但这是我将在 C++11 中执行的操作。
while (infile >> str1) {
vec.emplace_back(std::move(str1));
}
这个移动构造了向量后面的字符串,没有复制进去。我们可以这样做,因为我们不需要str1的内容,因为我们已经把它放入向量中。换句话说,不需要将它复制到向量后面的全新字符串中,只需将其内容移动到那里就足够了。 vec.push_back(str1); 的第一个循环可能可能会复制 str1 的内容,这确实是不必要的。
gcc 4.7.2 中的字符串实现目前为copy on write,因此两个循环的性能相同;您使用哪一个并不重要。暂时。
不幸的是,标准现在禁止在写入时复制字符串。我不知道 gcc 开发人员何时会更改实现。如果实现发生变化,无论您是移动 (emplace_back(std::move(s))) 还是复制 (push_back(s)),性能都可能会有所不同。
如果 C++98 兼容性对您很重要,请选择 push_back()。即使将来发生最糟糕的事情并且您的字符串被复制(现在没有被复制),该副本也可以转换为 memmove() / memcpy() 这非常快,很可能比读取内容更快来自硬盘的文件,因此文件 IO 很可能仍然是瓶颈。