Как прочитать «неравномерную» матрицу из файла и сохранить в 2D-массив? - PullRequest
0 голосов
/ 17 февраля 2019

Я работаю над экспериментом, который требует от меня перехода на C ++, который я все еще изучаю.Мне нужно прочитать данные из файла в 2D-массив, где данные в файле состоят из чисел с плавающей запятой, расположенных в матричном формате.Однако каждая строка матрицы в файле данных имеет различное количество столбцов, например:

1.24 3.55 6.00 123.5
65.8 45.2 1.0
1.1 389.66 101.2 34.5 899.12 23.7 12.1

Хорошая новость заключается в том, что я знаю максимальное количество возможных строк / столбцов, которое может иметь файл,и, по крайней мере, сейчас я не особо беспокоюсь об оптимизации памяти.Я хотел бы иметь двумерный массив, в котором соответствующие строки / столбцы совпадают с строками файла, а все остальные элементы имеют некое известное «фиктивное» значение.

У меня была идея циклически проходить по каждому из них.элемент файла (строка за строкой), распознать конец строки, а затем начать чтение следующей строки.К сожалению, у меня проблемы с выполнением этого.Например:

#include <iostream>
#include <fstream>

int main() {

const int max_rows = 100;
const int max_cols = 12;
//initialize the 2D array with a known dummy
float data[max_rows][max_cols] = {{-361}};

//prepare the file for reading
ifstream my_input_file;
my_input_file.open("file_name.dat");

int k1 = 0, k2 = 0; //the counters
while (!in.eof()) { //keep looping through until we reach the end of the file
    float data_point = in.get(); //get the current element from the file
    //somehow, recognize that we haven't reached the end of the line...?
        data[k1][k2] = next;
    //recognize that we have reached the end of the line
        //in this case, reset the counters
        k1 = 0;
        k2=k2+1;
}
}

И поэтому я не смог выяснить индексацию.Отчасти проблема в том, что, хотя я знаю, что символ "\ n" обозначает конец строки, он имеет другой тип по сравнению с числами с плавающей запятой в файле, и поэтому я в растерянности.Я думаю об этом неправильно?

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Вам не нужно знать пределы заранее, если вы придерживаетесь std::vector.Вот пример кода, который будет читать файл (при условии, что в нем нет плавающих элементов).

using Row = std::vector<float>;
using Array2D = std::vector<Row>;

int main() {
    Array2D data;
    std::ifstream in("file_name.dat");
    std::string line;
    Row::size_type max_cols = 0U;
    while (std::getline(in, line)) { // will stop at EOF
        Row newRow;
        std::istringstream iss(line);
        Row::value_type nr;
        while (iss >> nr) // will stop at end-of-line
            newRow.push_back(nr);
        max_cols = std::max(max_cols, newRow.size());
        data.push_back(std::move(newRow)); // using move to avoid copy
    }
    // make all columns same length, shorter filled with dummy value -361.0f
    for(auto & row : data)
        row.resize(max_cols, -361.0f);
}
0 голосов
/ 17 февраля 2019

Вот отправная точка, я буду работать над кодом, который вы можете использовать.Используйте двумерный вектор vector<vector<double>>, и вы можете использовать getline(), чтобы получить строку как string, чем использовать string stream, чтобы получить десятичные дроби из строки.

А вот и код

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

int main (void) {
    std::vector<std::vector<double>> matrix;

    std::ifstream inputFile;
    inputFile.open("test.txt");
    char line[99];
    for (int i = 0; inputFile.getline(line, sizeof(line)); ++i) {    
        std::stringstream strStream (line);
        double val = 0.0;
        matrix.push_back(std::vector<double>());
        while (strStream >> val)
            matrix[i].push_back(val);
    }

    return 0;
}
...