Извлечение чисел из итератора - PullRequest
0 голосов
/ 27 сентября 2018

В этом ТАКом вопросе есть блестящий ответ благодаря @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 

. Я изучал этот код уже два дня и не могу понять, какизвлечь числа из каждой строки.Итак, как я могу получить доступ, скажем, к 3-му номеру во второй строке (103) или, в более общем смысле, к n-му номеру в m-й строке?

Любое объяснение того, как работает это решение, тоже очень поможет!

1 Ответ

0 голосов
/ 27 сентября 2018

Используйте 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...