您可以通过吞咽换行来阻止istream或stringstream吗?

时间:2011-01-20 19:10:11

标签: c++ stl

对于我的家庭作业项目,我必须阅读一本书,然后逐字逐句解析,列出每个单词的出现次数以及找到的相应行。我现在已经完成了这个项目,并希望通过阅读其他人对STL的使用来优化我的代码(我们应该在很大程度上依赖于STL来完成这项任务)。

这不是关于家庭作业本身,而是我在每个单词中读到的两次尝试导致小溪吃掉了我的换行符。没有它们,我无法跟踪我正在阅读的文档中的哪条线,因此无法使用此类解决方案。

尝试一:

string word;
stringstream ss;
ss << document; // Document was read from file and stored in a "string document"
while(ss)
{
    ss >> word;
    // Work with the word.
    // Oops! No newlines anymore! :(
}

尝试二:

ifstream ifs(filename.c_str());
if(ifs.is_open)
{
    typedef istream_iterator<string> string_input;
    vector<string> words;
    copy(string_input(ifs), strin_input(), back_inserter(words));

    // Oops! The newlines are gone here too! :(
}

我目前的解决方案并不像我想要的那样漂亮,而且我想要更多的STL魔法(只是为了学习一些巧妙的STL技巧并让它变得更加舒适)

目前的解决方案:

阅读文件:

std::ostringstream os;
ss << ifstream(filename.c_str()).rdbuf();
return ss.str();

按行和单词分开:

size_t oldNewLine = 0;
size_t newLine = document_.find('\n', oldNewLine);
while(newLine != string::npos)
{
    string documentLine = document_.substr(oldNewLine, (newLine - oldNewLine));
    vector<string> words = Utility::split(documentLine);

   // Work with each individual word
   // Yay! I can keep track of the line number now! :)

   oldNewLine = newLine + 1; // Curse you, off by one error!
   newLine = document_.find('\n', oldNewLine);
}

文件的阅读简短,简洁,非常易读,但每行和单词的分割都很繁琐。我希望我能立即从文件中读取每个单词,保留换行符。必须有一个简短,甜蜜的方式来做到这一点!

那么,怎么做呢?

1 个答案:

答案 0 :(得分:3)

您可以逐行解析单词:

std::string line;
vector<string> words;

while(std::getline(ifs, line))
{
    std::stringstream linestream(line);

    copy(std::istream_iterator<std::string>(linestream),
         std::istream_iterator<std::string>(),
         std::back_inserter(words));

    ++lineCount;
}