CSV importing and storing in vectors as ints and floats

I have a csv file in the format of:
col1, col2, col3
54647, 656, 656
65654, 536, 656
65656, 656, 656

I want to store them in std::vectors using #include <sstream>
So far i have:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <iomanip>
#include <vector>
using namespace std;


//Gene Structure
struct  geneInfo {
    vector<int> ID;
    vector<float> length;
    vector<float> readCNT;
};

int main(){
    ifstream myfile;
    myfile.open("/Users/T_HEN1203/Desktop/DarkAerobic.csv");
    string unused;
    while ( getline(myfile, unused) ){
        ++numlines;
    }
    myfile.clear(); //resets error flag
    geneInfo Genes; //vectors for gene information 
    if ( myfile.open() ){
        //for loop for converting strings into floats and ints
        for (int row(0); row < numlines; ++row){
            string item;
            getline (myfile, item);
            stringstream iss(item);
            for (int col(0); col < 3; ++col){
                string line;
                getline (iss, line, ',');
                //used to break loop if the file stops reading
                if (!iss.good){
                    break;
                }
                stringstream convertor(line);
                convertor >> Genes.ID.push_back(row) >> Genes.length.push_back(row) >> Genes.readCNT.push_back(col);
            }
        }
    }
    return 0;
}

I think i need another for loop but im not 100% sure how to structure it. Would something like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for (int row(0); row < numlines; ++row){
            string item;
            getline (myfile, item);
            for (int row1(0); row1 < 3; ++row1){
                string item1
                getline (myfile, item1);
                stringstream iss(item1);
                for (int col(0); col < 3; ++col){
                    string line;
                    getline (iss, line, ',');
                    stringstream convertor(line);
                    convertor >> Genes.ID.push_back(row) >> Genes.length.push_back(row) >> Genes.readCNT.push_back(col);
                    //used to break loop if the file stops reading
                    if (!iss.good){
                        break;
                    }
                }
                
            }
        }
work?
Last edited on
Why the three vectors in your structure? Wouldn't a vector of your structure be better?

Also since you're using vectors there is no need to read the file to determine the number of records in the file.

Something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct geneInfo
{
    int ID;
    float length;
    float readCNT;
};

int main()
{
    // Better to use the constructor to open the file.
    ifstream myfile("/Users/T_HEN1203/Desktop/DarkAerobic.csv");

    // Don't forget to check that the file open operation succeeds!
...
    std::vector<geneInfo> genes;
    // Read the file;
    int id;
    float length, readCNT;
    char delimiter;

    // Read the file.
    while(myfile >> id >> delimiter >> length >> delimiter >> readCNT)
    {
        genes.push_back({id, length, readCNT});
    }
}
Last edited on
I included what you typed and i dont get any output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
struct geneinfo {
    int ID;
    float length;
    float readCNT;
};
//function protoypes
void print_geneinfo(geneinfo g);


int main(){

    double sumGCL, TPM, FPKM, sumCNTS;
    ifstream myfile("/Users/T_HEN1203/Desktop/DarkAerobic.csv"); //file opening constructor
    //Operation to check if the file opened
    if ( myfile.is_open() ){
        vector<geneinfo> genes;
        int id;
        float length, readCNT;
        char delimiter;
        // Read the file.
        while(myfile >> id >> delimiter >> length >> delimiter >> readCNT){
            genes.push_back({id, length, readCNT});
        }
        cout << "Gene ID" << "   DNA Length" << "   Read counts \n";
        for (int x(0); x < genes.size(); ++x){
            print_geneinfo( genes.at(0) );
        }
    }
    else{
        cerr<<"ERROR: The file isnt open.\n";
    }
    return 0;
}
//                         function definitions
//-----------------------------------------------------------------------
//function to print info
void print_geneinfo(geneinfo g){
    cout << g.ID << "  "<< g.length <<"  "<< g.readCNT << "\n";
}

Last edited on
I have a csv file in the format of:
col1, col2, col3
54647, 656, 656
65654, 536, 656
65656, 656, 656

Since it appears that the first line of your csv file is the heading text, you will need to skip that before starting to read the actual data. For example, you could put
 
    myfile.ignore(1000, '\n');
to ignore up to 1000 characters, or until the newline is found.

Also, line 27
 
            print_geneinfo( genes.at(0) );
should probably be
 
            print_geneinfo( genes.at(x) );

Last edited on
Haha always the little things!
Thank you everybody for the help and here is the final code for anybody interested:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
struct geneinfo {
    int ID;
    float length;
    float readCNT;
};
//function protoypes
void Print_geneinfo(geneinfo g);

int main(){

    ifstream myfile("/Users/T_HEN1203/Desktop/DarkAerobic.csv"); //file opening constructor
    //Operation to check if the file opened
    if ( myfile.is_open() ){
        vector<geneinfo> genes;
        int id;
        float length, readCNT;
        char delimiter;
        // Read the file.
        myfile.ignore(1000, '\n');
        while(myfile >> id >> delimiter >> length >> delimiter >> readCNT){
            genes.push_back({id, length, readCNT});
        }
        cout  << "Gene ID" << "   DNA Length" << "   Read counts \n";
        for (int x(0); x < genes.size(); ++x){
            Print_geneinfo( genes.at(x) );
        }
    }
    else{
        cerr<<"ERROR: The file isnt open.\n";
    }
    return 0;
}
//                             function definitions
//------------------------------------------------------------------------------
//function to print info
void Print_geneinfo(geneinfo g){
    cout << g.ID << "  "<< g.length <<"  "<< g.readCNT << "\n";
}

EDIT: Everything seems to work and it displays correctly. It looks like im not using #include <sstream> anymore and i read somewhere that csv files are read as strings so i was curious as to what converts it to int and float?
Last edited on
i read somewhere that csv files are read as strings

Presumably that was just one possible approach which you read about. As you can see, the code suggested by jlb does not follow that approach. The choice is yours. A csv file is after all just a text file, you can handle it in whichever way seems best.

so i was curious as to what converts it to int and float?

It's just the same in principle as when you do cin >> id; or cin >> length;. That is, the input is in the form of text and the >> operator of the stream does the conversion for you.
Last edited on
Thank you!
Topic archived. No new replies allowed.