C ++ читает числа из файла и сохраняет в векторах - PullRequest
1 голос
/ 16 сентября 2010

У меня возникли проблемы с "отменой" этого метода, который по существу выгружает матрицу чисел переменного размера в текстовый файл:

void vectorToFile(char *name, vector<vector<double>>* a){
    FILE* fp = fopen(name, "w");
    for(int i=0;i<a->size();i++){
        for(int j=0;j<a->at(i).size();j++){
            fprintf(fp, "%f ", a->at(i).at(j));
        }
        fprintf(fp, "\n");
    }
    fclose(fp);
}

У меня проблемы с реализацией обратного:

vector<vector<double>> fileToVector(char *name){ ??? }

Я гарантирую, что числа в файле образуют «прямоугольник», то есть все размеры внутренних векторов равны, но я не знаю, как определить количество записей в строке и количествоколонны.

Кто-нибудь может указать мне правильное направление?Каждый найденный мной пример реализует нечто гораздо более простое, с жестко заданным размером или размерами, указанными в первом ряду (что, к сожалению, я не могу себе позволить)

Ответы [ 5 ]

10 голосов
/ 16 сентября 2010

Я новичок в C ++, поэтому я не уверен, является ли это хорошим подходом или нет, но я бы открыл файл, прочитал входные данные построчно, анализируя каждую строку, когда я ее читал. Вот пример кода (непроверенный, не скомпилированный):

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

std::vector<std::vector<double> > fileToVector(const char *name)
{
    std::vector<std::vector<double> > result;
    std::ifstream input (name);
    std::string lineData;

    while(getline(input, lineData))
    {
        double d;
        std::vector<double> row;
        std::stringstream lineStream(lineData);

        while (lineStream >> d)
            row.push_back(d);

        result.push_back(row);
    }

    return result;
}
2 голосов
/ 16 сентября 2010

Вы можете попробовать другой подход C ++ ish:

void vectorToFile(std::vector<double> const& vec, std::string const& filename) {
    std::ofstream file(filename);
    if(file.good()) {
        file.flags(std::ios::fixed);
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<double>(file));
    } else {
        // throw error or sth
    }
    file.close();
}

Если вы хотите сохранить как двоичный файл, вы можете использовать ostream_binary_iterator как этот - http://bit.ly/9JAxdp:

void vectorToFile(std::vector<double> const& vec, std::string const& filename) {
    std::ofstream file(filename, std::ios::binary);
    if(file.good()) {
        file.flags(std::ios::fixed);
        std::copy(vec.begin(), vec.end(), ostream_binary_iterator<double>(file));
    } else {
        // throw error or sth
    }
    file.close();
}
1 голос
/ 16 сентября 2010

Было бы проще, если бы вы использовали C ++ I / O вместо C I / O. Я бы предложил использовать ifstream для чтения в файле и getline() для чтения каждой строки. Каждая строка - это числа, которые должны входить в vector. Вероятно, самый простой способ анализа string - использовать stringstream. Затем вы можете разобрать каждый double и push_back() на vector, так что вам не придется заботиться о размере vectors. Я бы также предложил использовать std::string вместо char* везде, где вы можете (хотя для имен файлов вы, как правило, в конечном итоге вынуждены использовать c_str() для них, так как файловые операции ввода-вывода всегда, кажется, занимают const char* вместо std::string).

0 голосов
/ 16 сентября 2010

Есть ли какая-либо конкретная причина использовать вектор> вместо использования просто double ** и использования new double [] для выделения массива и каждого подэлемента?Я предполагаю, что размер массива может быть динамически изменен во время выполнения, но если массив выделяется только один раз, использование double ** должно быть намного более эффективным, чем итерация по вектору.решение вашей проблемы - сбросить границы массива в файл и прочитать его обратно ...

0 голосов
/ 16 сентября 2010

Вы можете читать строки, разделять, используя разделитель, который у вас есть, а затем анализировать числа.Вы можете использовать getline для чтения строк как строк, и вам не нужно будет знать точное число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...