LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Reading in data in columns from a file (C++) (https://www.linuxquestions.org/questions/programming-9/reading-in-data-in-columns-from-a-file-c-422806/)

Nylex 03-08-2006 07:27 AM

Reading in data in columns from a file (C++)
 
Hi people, I have a file with some data in columns (separated by tabs) like so:

Code:

1.23        1.354        2.78
1.44        10.023        2.756
2.31        20.3        10.07

What I need to do is read each line of the file in and put each column in an array/vector (i.e. the first number in each line should go in one array, second number in each line in another, third number in yet another array, if that makes sense). I found a similar thread using strtok() (though the data was delimited by commas, not tabs) here, but I don't know how to get each line read into a char[] for strtok(). I can read into a string, though, but then using string's c_str() gives me a const char*.

Any ideas on how to do what I need?

Thanks!

xhi 03-08-2006 08:27 AM

well if you know the structure of the file is always going to be like that, you can use the stream extractor >> operator with ifstream

ex
Code:

double cola, colb, colc;
ifstream in(file);
while(!in.eof()){
  in >> cola;
  in >> colb;
  in >> colc;
}


dmail 03-08-2006 09:09 AM

<edit> My browser hadn't refreshed so I didn't see xhi's post.
</edit>
Please not this code expects you to know the number of cols and rows and does not delete the memory, but it shows you how to do what you ask.
Code:

#include <fstream>
#include <iostream>
#include <string>
float** read_file(std::string filename,int rows,int cols)
{
        std::fstream file;
        file.open(filename.c_str(), std::ios::in);
        if(!file.is_open()){return 0;}

        float** floats = new float*[cols+1];
        for(int i = 0; i <cols;++i){ floats[i] = new float[rows+1]; }

        //read each row
        for(int i =0;i<rows;++i)
        {
                for(int j =0;j<cols;++j)//push into the col
                { file >>floats[j][i]; }
        }
        file.close();

        return floats;
}

int main()
{
        int rows = 3;
        int cols = 3;
        float** floats;
        if( !(floats = read_file("test",rows,cols) ) ){return 0;}

        //write out the data
        for(int i =0;i<rows;++i)
        {
                for(int j =0;j<cols;++j){ std::cout <<floats[j][i] <<"\t"; }
                std::cout <<"\n";
        }
        char wait;
        std::cin >>wait;

        return 0;
}

test
1.23 1.354 2.78
1.44 10.023 2.756
2.31 20.3 10.07

output
1.23 1.354 2.78
1.44 10.023 2.756
2.31 20.3 10.07

Nylex 03-08-2006 02:28 PM

Thank you both for the replies.

xhi, your example does pretty much what I need (with a slight modification to use arrays and stuff, but that was easy enough for me to do). I don't know why I thought that doing that wouldn't work. I was trying to use getline() and stuff.

dmail, I didn't really understand your code to be honest and I've never had to use double pointers before (I assume that's what you call them, but obviously I could be wrong). However, thank you again for taking the time to write it as it is appreciated!

dmail 03-08-2006 05:55 PM

Good to hear it that you have have sorted Nylex. I would never have written the code if I had seen xhi's post, but maybe i should add some comments so that anyone in future can understand it.

Code:

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

/*param filename :the name of the file to open
param rows      :number of rows in the file data
param cols      :number of columns in the files data
return float**  :a 2d float array holding the read in values
                        or NULL on failure.*/
float** read_file(std::string filename,int rows,int cols)
{
        std::fstream file;//create a stream for the file
        file.open(filename.c_str(), std::ios::in);//open the file to read in
        if(!file.is_open()){return 0;}//if the file failed to open return NULL

        //float** is just a 2d array like float values[cols][rows]
        //create the column pointers
        float** floats = new float*[cols+1];
       
        //create the row pointers
        for(int i = 0; i <cols;++i){ floats[i] = new float[rows+1]; }

        //read each through each row
        for(int i =0;i<rows;++i)
        {
                //read the values in this row and push into the correct
                //column.floats is [cols][rows]
                for(int j =0;j<cols;++j)//push into the col
                { file >>floats[j][i]; }
        }
        file.close();//close the file

        return floats;//return the 2d array
}

int main()
{
        int rows = 3;//number of rows in the file
        int cols = 3;//number of columns in the file
        float** floats;//2d array
       
        /*the func read_file returns null on failure, so set floats to the
        value returned (which should be a 2d array) and check for failure.
        if the function failed exit main.*/
        if( !(floats = read_file("test",rows,cols) ) ){return 0;}

        //write out the data reading through the columns and rows
        for(int i =0;i<rows;++i)
        {
                for(int j =0;j<cols;++j){ std::cout <<floats[j][i] <<"\t"; }
                std::cout <<"\n";
        }
        char wait;
        std::cin >>wait;

        return 0;
}



All times are GMT -5. The time now is 11:39 AM.