我有以下文本文件:
0 0 0 0 0 1 0 0 2 3 4 2 1 2 1
0 0 0 0 2 7 5 4 5 7 5 4 3
3 2 4 6 2 7 2 7 5 4 5 7 5 4 3
3 2 4 6 2 7 2 7 5 4 5 4 3
0 0 0 0 0 1 0 2 3 4 2 1 2 1
0 0 0 0 0 1 0 0 2 3 4 2 1 2 1
0 0 0 0 2 1 2 1
3 2 4 6 2 7 2 7 5 4 5 7 5 4 3
3 2 4 6 2 0 2 3 4 2 1 2 1
0 0 0 0 0 1 0 0 2 3 4 2 1 2 1
3 2 4 6 2 7 2 7 5 4 5 7 5 4 3
我可以用以下程序阅读:
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::ifstream is("numbers.txt");
std::string line;
std::vector<std::vector<int>> numbers{};
while (std::getline(is,line)) {
std::stringstream ss{line};
std::istream_iterator<int> start{ss},end;
numbers.emplace_back(start,end);
std::cout << "Read " << numbers.back().size() << " numbers in row\n";
}
std::cout << "Read " << numbers.size() << " rows\n";
std::cout << "numbers read in:\n";
for (auto row : numbers) {
for (auto number : row) {
std::cout << number << " ";
}
std::cout << "\n";
}
std::cout << std::endl;
}
我想在循环外只创建一次std::stringstream
和std::istream_iterator
。每次循环在以下程序中执行时,如何将迭代器调整到正确的位置?
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::ifstream is("numbers.txt");
std::string line;
std::vector<std::vector<int>> numbers{};
std::stringstream ss{line};
std::istream_iterator<int> start{ss},end;
while (std::getline(is,line)) {
ss << line;
//start = ss.beg;
numbers.emplace_back(start,end);
std::cout << "Read " << numbers.back().size() << " numbers in row\n";
}
std::cout << "Read " << numbers.size() << " rows\n";
std::cout << "numbers read in:\n";
for (auto row : numbers) {
for (auto number : row) {
std::cout << number << " ";
}
std::cout << "\n";
}
std::cout << std::endl;
}
答案 0 :(得分:1)
为了使第二种方法有效,必须解决两个问题:
std::stringstream
ss
必须清除eof
标记,以便可以再次使用。为此,我们可以使用ss.clear()
。ss
,就必须重置std::istream_iterator
,以便它可以看到来自std::stringstream
的新输入。这里的关键是要意识到,只要构造它,迭代器就会读取它将提供的第一个值。然后程序变为:
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::ifstream is("numbers.txt");
std::string line;
std::vector<std::vector<int>> numbers{};
std::stringstream ss{line};
std::istream_iterator<int> start{ss},end;
while (std::getline(is,line)) {
ss.clear(); // clear eof flag
ss << line; // ok to add data
start = ss; // reset the iterator so that it will see the new data
numbers.emplace_back(start,end);
std::cout << "Read " << numbers.back().size() << " numbers in row\n";
}
std::cout << "Read " << numbers.size() << " rows\n";
std::cout << "numbers read in:\n";
for (auto row : numbers) {
for (auto number : row) {
std::cout << number << " ";
}
std::cout << "\n";
}
std::cout << std::endl;
}
在Visual Studio 2015中,我执行了以下操作:
我运行了两个版本的程序,其中有很多条目 没有明显的区别。
在这两种情况下,大部分时间都花在构造迭代器上
因为声明start = ss;
似乎在调用
无论如何都是构造函数。