我有一个空格分隔的文件,看起来很像:
4 55 -1.8
4 61 -1.8
2 37 -1.56739
9 1 -1.23
29 8 -1.918
4 57 -1.2
54 63 -1.118012
我写了下面的代码,一行一行地读到了vetors:
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<int> row1 = {};
std::vector<int> row2 = {};
std::vector<double> row3 = {};
int row1val, row2val;
double row3val;
std::string line;
// read input a line at a time until end-of-file
while (std::getline(std::cin, line))
{
std::cin >> row1val >> row2val >> row3val;
row1.push_back(row1val);
row2.push_back(row2val);
row3.push_back(row3val);
}
std::cout << row1[0] << " " << row2[0] << " " << row3[0] << std::endl;
return 0;
}
我认为有很多问题:
1)第一行数据不存储在向量中。
2)代码看起来非常不优雅,比如使用line
和变量s row1val
等。有没有办法简化它?
答案 0 :(得分:1)
您正在通过调用std::cin
并使用格式化输入来阅读getline()
。你可能想要坚持一个或另一个。
while (std::cin >> row1val >> row2val >> row3val)
{
row1.push_back(row1val);
row2.push_back(row2val);
row3.push_back(row3val);
}
这个风险是它会接受比三个元素更短或更长的行,&#34;窃取&#34;来自下一行的元素。
为了避免这种风险,您只需使用getline()
从cin
读取,然后解析生成的缓冲区:
while (std::getline(std::cin, line))
{
std::istringstream linebuf(line);
if( linebuf >> row1val >> row2val >> row3val) {
row1.push_back(row1val);
row2.push_back(row2val);
row3.push_back(row3val);
}
}
为了避免临时变量和row1val
等的重复,您可以创建一个类,并将数据存储在该类的单个向量中,而不是三个向量。这是一个完整的示例程序。请注意,它包括基于getline()
和格式化输入的解决方案供您选择。
无论您选择哪个operator>>
,请注意main()
函数变得多么简单。
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
struct row_t {
int row1val, row2val;
double row3val;
friend std::istream& operator>>(std::istream&is, row_t& r) {
#ifdef USE_GETLINE
std::string line;
if(std::getline(is, line) &&
std::istringstream(line) >> r.row1val >> r.row2val >> r.row3val) {
return is;
}
is.setstate(std::ios::failbit);
return is;
#else
return is >> r.row1val >> r.row2val >> r.row3val;
#endif
};
};
int main() {
std::vector<row_t> rows((std::istream_iterator<row_t>(std::cin)),
std::istream_iterator<row_t>());
std::cout << rows[0].row1val << " " << rows[0].row2val << " " << rows[0].row3val << std::endl;
std::cout << rows.size() << "\n";
return 0;
}