从迭代器中提取数字

时间:2018-09-27 18:53:24

标签: c++ iterator

this这样的问题中,由于@HowardHinnant提供了一个绝妙的答案,该答案非常有效地将文本文件中的数字提取到向量中。这是简洁的代码:

#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

// g++ -std=c++11 test.cpp -o t

int main()
{
    std::ifstream theStream("data.txt"); 
    if( ! theStream )
          std::cerr << "data.txt\n";
    while (true)
    {
        std::string line;
        std::getline(theStream, line);
        if (line.empty())
            break;

        std::istringstream myStream( line );
        std::istream_iterator<int> begin(myStream), eof;
        std::vector<int> numbers(begin, eof);

        // process line however you need
        std::copy(numbers.begin(), numbers.end(),
                  std::ostream_iterator<int>(std::cout, " "));
        std::cout << '\n';
    }
}

数据样本为

800 170 84 439 
129 902 103 492 394 140 496 893 
229 645 
164 389 74 208 726 315 
291 421 230 789 246 791 762 
416 241 538 810 605 
714 555 54 863 
288 465 563 831 
0 339 740 427 718 
449 675 545 842 779 607 
274 958 

我已经研究了这两天的代码,还不太了解如何从每一行中提取数字。那么,我怎样才能访问第二行(103)上的第三个数字,或更一般地说,第m行上的第n个数字呢?

任何有关此解决方案如何工作的解释也将真正有帮助!

1 个答案:

答案 0 :(得分:2)

使用vector中的vectors分别存储每行编号:

#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

int main()
{
    std::ifstream theStream("data.txt");
    if (!theStream)
        std::cerr << "data.txt\n";

    std::vector<std::vector<int>> data;  // vector to hold the numbers of each line seperately
    while (true)
    {
        std::string line;
        std::getline(theStream, line);
        if (line.empty())
            break;

        std::istringstream myStream(line);
        std::istream_iterator<int> begin(myStream), eof;
        std::vector<int> numbers(begin, eof);

        // process line however you need
        data.push_back(numbers); // add numbers of current line to data
    }

    std::cout << data[1][2] << '\n'; // 2nd row, 3rd number: 103
}
  

假设查询仅进行一次,则可以通过计算提取时(以及while循环的每次迭代)所处的行和列来一次完成查询;然后从那里休息。这样一来,您不必读取整个文件。

可能看起来像这样:

#include <cstddef>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>

int main()
{
    std::ifstream theStream("data.txt");
    if (!theStream)
        std::cerr << "data.txt\n";

    std::size_t target_row = 2;  // 1-based
    std::size_t target_col = 3;  // 1-based

    int value = 0;
    int valid = false;

    for (std::size_t current_row = 1; true; ++current_row)
    {
        std::string line;
        if (!std::getline(theStream, line) || line.empty())
            break;

        if (current_row != target_row)
            continue;

        std::istringstream myStream(line);
        for (std::size_t current_col = 1; myStream >> value; ++current_col)
            if (current_col == target_col) {
                valid = true;
                break;
            }           

        break;
    }

    if (!valid)
        std::cerr << "No such row and column!\n\n";
    else
        std::cout << value;
}