#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
EDIT ::
为了澄清,矢量元素是正确构造的。如果我从for(auto a:vec)打印输入,它会像文件一样逐行给我。当我尝试从向量中的每个字符构建单词时。我问我该怎么做才能指明有一个新行,以便
line += a[i]
在点击一行结尾时不会继续添加到行。
答案 0 :(得分:2)
不要做
while (!in.eof()) { ... }
它不会像你期望的那样工作。
取而代之的是
while (std::getline(...)) { ... }
原因是因为eof
标志未设置,直到您在文件结束时实际尝试读取为止。这意味着您将循环一次到多次,尝试读取不存在的行,然后将其添加到向量中。
还有另一种分离单词&#34;在空间边界上,使用std::istringstream
和普通输入操作符>>
:
std::istringstream is{a};
std::string word;
while (is >> word)
{
// Do something with `word`
}
答案 1 :(得分: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
〜&gt;打印单词“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 = "";
}
}
答案 2 :(得分: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;
}