0
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>
int main(int argc, char *argv[])
{
    std::vector<std::string> vec;
    std::string line;
    std::ifstream in(argv[1]);
    while(!in.eof()) {
        std::getline(in,line);
        vec.push_back(line);
    }
    std::istringstream is;
    line = "";
    for(auto a:vec) {
        for(auto i = a.begin(); i != a.end(); i++) {
            if(!(isspace(*i) | ispunct(*i)))
                line += *i;
            else {
                is.str(line);
                std::cout << is.str() << std::endl;
                line = "";
            }
        }
    }
    std::cout << is.str() << std::endl;
    return 0;
}

我编写了一个程序,它接受一个文件并将每一行放入一个字符串向量中。然后从元素中一次读取一个单词。

当我从向量中读取时,我无法指定新行。我的输出连接了一行的结尾和下一行的开头。如何指定有一个新行?

我正在阅读的文件内容:

Math 3 2
Math 4 3
Math 5 4
Phys 3 1
Math 3 1
Comp 3 2

我得到的输出:

Math
3
2Math
4
3Math
5
4Phys
3
1Math
3
1Comp
3
3

编辑::

澄清一下,向量元素的构造是正确的。如果我从 for(auto a:vec) 打印一个 in,它会像文件一样逐行给我。当我尝试从向量中的每个字符构建单词时。我在问我该怎么做才能指定有一个新行,以便

line += a[i] 

当它到达一行的末尾时不会继续添加到行。

4

3 回答 3

2

不要做

while (!in.eof()) { ... }

它不会按您期望的方式工作。

而是做

while (std::getline(...)) { ... }

这样做的原因是,eof直到您实际尝试读取文件末尾时才设置标志。这意味着您将循环一次到多次,尝试读取不存在的行,然后将其添加到向量中。


还有另一种在空间边界上分隔“单词”的方法,通过使用std::istringstream和普通输入运算符>>

std::istringstream is{a};

std::string word;
while (is >> word)
{
    // Do something with `word`
}
于 2013-09-04T14:34:41.843 回答
1

这里的实际问题是代码逻辑错误。这是您在打印输出时所做的伪代码:

for every line:
    for every character in the line:
        if it is alphanumerical character
            then add it to the word
        else
            print the so-far built word

现在看行Math 4 3~> 在打印单词“4”之后,此代码将字符添加'3'到行中但不将其打印为单词,因此3是下一行单词的开头。

另请注意,您的代码远比必要的复杂。它可能看起来像这样:

std::string word;
for (size_t i = 0; i < vec.size(); ++i) {
    std::istringstream lineStream(vec[i]);
    while (lineStream >> word)
        std::cout << word << std::endl;
}

但是,如果您想保留原始代码,可以采取以下措施来解决此问题:

line = "";
for(auto a:vec) {
    for(auto i = a.begin(); i != a.end(); i++) {
        if (isalnum(*i))
            line += *i;
        else {
            std::cout << line << std::endl;
            line = "";
        }
    }

    // before we start processing the next element...
    // in case there's another line to be printed:
    if (!line.empty()) {
        // print the line and reset the variable:
        std::cout << line << std::endl;
        line = "";
    }
}
于 2013-09-04T14:57:48.423 回答
0

您也可以使用这样的向量逐行读取;

向量定义;

    struct VectorName {
       std::string str;
       float num1;
       float num2;
};

std::vector <VectorName> smthVector_;

函数的使用

   VectorName vector;
   std::string str;
   char buf_1[50];
   while(std::getline(in, str))
   {
       if(sscanf(str.c_str(), "%s %f %f", buf_1, &vector.num1, &vector.num2) == 3)
       {
           vector.str = buf_1;
           smthVector_push_back(vector);
       }
        else
            std::cout << "No param in string  " << str << std::endl;
   }
于 2013-09-04T14:45:26.137 回答