1

Im having a problem trying to figure out why my file is returning 0's instead of the numbers inside the file, here is the code I did in C++ on reading a file:

    #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;
    } 

And here is a sample of my file containing the values I want to extract from it:

20.0

20.0

20.0

20.0

20.0

200.0

20.0

200.0

Hope someone can help me out since I researched some info about this and didn't really find a solution.

Novazero
  • 553
  • 6
  • 24
  • Is there a question? There is no code using this, and as it is, it might just work. Does your input contain empty lines? It better not – sehe May 01 '11 at 20:15
  • Well this isn't all my code I just wanted to display the area in my code that I was seeing the issue in. – Novazero May 01 '11 at 20:19
  • How are you calling this function? Can you show the code that uses this function? – Doug T. May 01 '11 at 20:23
  • Yeah I just edited my post and added a pastebin link to my code that I have so far. – Novazero May 01 '11 at 20:30
  • @Novazero: your pastebin link will expire in 24h - how useful do you think that will be in, say, a day? Please inline the code into your question. – Marc Mutz - mmutz May 01 '11 at 20:33
  • You should probably put in a bunch of printfs or step through the code with a debugger to figure out where it's going wrong. Nothing obvious comes to mind while looking at your code. – Himadri Choudhury May 01 '11 at 20:43

3 Answers3

1

Your reading and printing code appears to work, but your command line reading code may have some problems.

I ran your code without getting command line arguments. The following code, is pretty much copy-pasted from your main minus getting command line args.

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;
}

With the input you provide, I get the output:

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

However looking at your command line arg reading code, I can see some potential problems. First you use atoi(). When atoi fails, it returns 0. Do you know that this code is working? Is everything getting initialized correctly? Or is atoi failing on the input, causing n to be 0 and therefore causing nothing to be read in? (You may wish to look into stringstreams for doing this kind of thing).

Moreover, when argc is not 6, you're silently failing and reading from uninitialized global memory. This memory is garbage. Do you know that this is not happening? If you're just doing:

  your.exe test.dat 5

then 5 isn't going to be read from the command line because argc is not 6. Are you always passing 6 arguments like you should when testing? Maybe not, cause in its current state your code really only needs the file name and size.

Most important thing, see if you're getting what you expect from the command line.

PS This is g++:

$ g++ --version g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Doug T.
  • 64,223
  • 27
  • 138
  • 202
  • Well here is the issue the size of my array will be made during runtime through the GetCommandLineArguments command that I show in my post. All my code is shown in my edited first post. – Novazero May 01 '11 at 20:42
  • Ill take a look at checking my commandline function I created I believe your right that it might be changing the values – Novazero May 01 '11 at 20:57
  • well here is an example on what I need to input through command line p1.exe sample.input 8 4 16 100. Does the p1.exe count as a commandline argument then? – Novazero May 01 '11 at 21:01
  • @Novazero yes it counts as one. argv[0] is the name of the executable. – Doug T. May 01 '11 at 21:03
  • Hmm well it definitely passes the value 5 back if I use the command line and all the other functions contain the number 5 for its n. – Novazero May 01 '11 at 21:10
  • Well I did edit my code to only read 3 arguments atm, and it still displays zeros, and like I said my n is equal to 5 throughout my whole code wherever n is used. Im going to try to use stringstreams and see what difference it makes. – Novazero May 01 '11 at 21:17
  • @Novazero, there's a lot you can try to debug -- what happens when you print out the values as they're read? Are they coming from the file correctly? Can you printout the matrix at that point? Is the matrix getting filled out there but just not passed back correctly? Is the problem in your print routine? Is everything getting passed correctly there? – Doug T. May 01 '11 at 21:20
  • I did this to my readFile function and got a bunch of zero's being read before the values even get put into my array: std:: cout<< myfile; – Novazero May 01 '11 at 21:24
0

I suggest a fixup like this, making things more robust:

#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;
}
sehe
  • 374,641
  • 47
  • 450
  • 633
0

Your input operator will read the numbers but leave the line breaks in the file.

See this answer about how to ignore() the end-of-line after reading your values

Why would we call cin.clear() and cin.ignore() after reading input?

Community
  • 1
  • 1
Bo Persson
  • 90,663
  • 31
  • 146
  • 203