Проблема с чтением файла, содержащего десятичные дроби - PullRequest
1 голос
/ 02 мая 2011

У меня проблема с попыткой выяснить, почему мой файл возвращает 0 вместо чисел внутри файла, вот код, который я сделал на C ++ при чтении файла:

    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    #include <string>

    using namespace std;

    string cfile;
    int cnum1,cnum2,cnum3,cnum4;
    bool fired = false;



    /*
     * 
     */

    void printMatrix(double **x, int n)
    {
        int size = n;
        for(int i=0; i<size; i++)
        {
            for(int j=0; j<size; j++)
            {
                std:: cout << x[i][j] << " " ;
            }
            std:: cout << std::endl;
        }


    }

    void readFile(string file,double **x, int n)
    {
        std::ifstream myfile(file.c_str());

        int size = n;
        for(int i=0; i<size; i++)
        {
            for(int j=0; j<size; j++)
            {
                myfile >> x[i][j];
            }
        }
    }

    void GetCommandLineArguments(int argc, char **argv,string &file, int &n, int &k, int &m, int &i)
    {
        if( argc == 6 )
        {
            cfile = argv[1];
            cnum1 = atoi(argv[2]);
            cnum2 = atoi(argv[3]);
            cnum3 = atoi(argv[4]);
            cnum4 = atoi(argv[5]);
        }
        file = cfile;
        n = cnum1;
        k = cnum2;
        m = cnum3;
        i = cnum4;

    }



    int main(int argc, char** argv) {

        int k; //Factor of n
        int m; //Innner matrix size
        int i; //Iteration
        int n; //Matrix Size
        string file;


        GetCommandLineArguments(argc, argv, file, n, k, m, i);

        double **matrix;

        matrix = new double*[n];
        for(int i = 0; i<n; i++)
            matrix[i] = new double[n];

        for(int j=0; j<n; j++)
            for(int i=0; i<n;i++)
                matrix[i][j] = 0;

        readFile(file, matrix, n);
        printMatrix(matrix, n);



        return 0;
    } 

А вотобразец моего файла, содержащий значения, которые я хочу извлечь из него:

20.0

20.0

20.0

20.0

20.0

200.0

20.0

200.0

Надеюсь, кто-нибудь может мне помочь, так как я изучил некоторую информацию об этом и не нашел решения.

Ответы [ 3 ]

1 голос
/ 02 мая 2011

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

Я запустил ваш код без аргументов командной строки. Следующий код в основном скопирован из вашего основного минуса с получением аргументов командной строки.

int main()
{
    double **matrix;
    std::string file = "test.dat";
    int n = 5;

    matrix = new double*[n];
    for(int i = 0; i<n; i++)
        matrix[i] = new double[n];

    for(int j=0; j<n; j++)
        for(int i=0; i<n;i++)
            matrix[i][j] = 0;

    readFile(file, matrix, n);
    printMatrix(matrix, n);

   return 0;
}

С предоставленным вами вводом я получаю вывод:

20 20 20 20 20
200 20 200 0 0
0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Однако глядя на код чтения вашей командной строки, я вижу некоторые потенциальные проблемы. Сначала вы используете atoi (). Когда происходит сбой atoi, он возвращает 0. Знаете ли вы, что этот код работает? Все ли правильно инициализируется? Или atoi терпит неудачу на входе, приводя к тому, что n равно 0 и, следовательно, ничего не читается? (Вы можете захотеть заглянуть в струнные потоки для выполнения подобных действий).

Более того, когда argc не равен 6, вы молча терпите неудачу и читаете из неинициализированной глобальной памяти. Эта память является мусором. Вы знаете, что этого не происходит? Если вы просто делаете:

  your.exe test.dat 5

тогда 5 не будет считываться из командной строки, потому что argc не равен 6. Всегда ли вы передаете 6 аргументов, как при тестировании? Возможно, нет, потому что в его текущем состоянии вашему коду нужны только имя и размер файла.

Самое главное, посмотрите, получаете ли вы то, что ожидаете от командной строки.

PS Это г ++:

$ g ++ - версия g ++ (Ubuntu / Linaro 4.4.4-14ubuntu5) 4.4.5 Copyright (C) 2010 Free Software Foundation, Inc. Это бесплатно программного обеспечения; см. источник для копирования условия. Там нет гарантии; не даже для ТОРГОВЛИ или ФИТНЕСА ДЛЯ ОСОБЕННОЙ ЦЕЛИ.

0 голосов
/ 02 мая 2011

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

См. Этот ответ о том, как ignore() конец строки после чтения ваших значений

Почему мы будем вызывать cin.clear () и cin.ignore () после чтения ввода?

0 голосов
/ 02 мая 2011

Я предлагаю исправление, подобное этому, чтобы сделать вещи более надежными:

#include <fstream>
#include <iostream>
#include <string>
#include <stdexcept>

template <size_t size>
    void readFile(std::string file, double (&x)[size][size])
{
    std::ifstream myfile(file.c_str());

    for(int i=0; i<size; i++)
    {
        for(int j=0; j<size; j++)
        {
            if (!(myfile >> x[i][j]))
                throw std::runtime_error("Couldn't read double from " + file);
        }
    }
}

int main(int argc, const char *const args[])
{
    try
    {
        double data[10][10];
        readFile("input.txt", data);
    } catch(const std::exception& e)
    {
        std::cerr << "Whoops: " << e.what() << std::endl;
        return 255;
    }

    return 0;
}
...