Read multiple text files bug

Hey, guys. Can u help me with the piece of code? So, I must read a text file that contains the name of CSV files that will be in the same folder called "data". I've tried to do it, but it is just reading the first CSV file and not the other ones. I am storing the data within the CSV file in another class.

Here is the piece of code that I did:

int main()
{
std::ifstream file("data/met_index.txt"); //this is the TXT file containing the CSV files name
if(!file) return -1;

std::vector<std::string> csvFiles; //I decided to use a vector as I am not sure how many CSV files will be
std::string temp;
WindLog windlog;

while(file)
{
getline(file, temp);
csvFiles.push_back(temp);
}

for(int i = 0; i < csvFiles.size(); i++)
{
std::string fileName = "data/" + csvFiles[i]; //I am creating a string that will be "data/...CSVFILENAME" as I am reading only the CSV name in the TXT
std::ifstream inFile(fileName.c_str());
if(!inFile) return -1;
inFile >> windlog; //Here I am reading and storing the CSV file in another class
inFile.close();
}

menu(windlog);

return 0;
}

Cheers, guys.
Last edited on
1
2
3
4
for(int i = 0; i < csvFiles.size(); i++)
{
   std::string fileName = "data/" + csvFiles[i];
   std::cout << fileName << '\n';        // Put this line in and tell us what your program says. 




Also, your earlier file read would be better as
1
2
3
4
while( getline(file, temp) )
{
   csvFiles.push_back(temp);
}

The filestream doesn't go into a failed state until it has tried to read something ... by which time you are committed to running the loop. You will probably end up with the last entry repeated.
Last edited on
Hey, thanks for the reply. It is printing this:

data/MetData_Jan01-2011-Jan01-2012-ALL.csv
data/MetData_Jan01-2010-Jan01-2011-ALL.csv
data/MetData_Jan01-2012-Jan01-2013-ALL.csv
data/MetData_Jan01-2013-Jan01-2014-ALL.csv
data/MetData_Mar01-2014-Mar01-2015-ALL.csv
data/MetData_Mar01-2015-Mar01-2016-ALL.csv

The CSV files names are right. But it still just saving the first CSV.

And yeah, thanks for the other tip. It was actually repeating the last CSV. Now it's not. Cheers.
What code have you used to overload the >> operator in
inFile >> windlog;

Also, have you checked the contents of those .csv files with a text editor?

Yes, I have. I also tried to change the position in the TXT file of the CSV files names. For example, I have tried to put MeData_Jan01-2011-2012 first and it was reading fine, than I tried with 2012-2013 first and it was also reading fine. So, there is no problem in the CSV.

I have used this code:

I am reading just some columns of the CSV file. Moreover, I am saving each column in a different class. For example: first column I have date and time, and I am saving date in Date class and time in Time class.

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
istream & operator >>(istream & file, WindLog & w)
{
    Date temp_d; 
    Time temp_t;
    WindSpeed temp_s;
    SolarRadiation temp_rad;
    AirTemperature temp_air;

    std::string Line;
    int row_count = 0;

    while(getline(file, Line))
    {
        row_count += 1;

        std::stringstream lineStream(Line);
        std::string cell;
        int column_count = 0;

        while(getline(lineStream, cell, ','))
        {
            column_count += 1;
            if(row_count >= 2)
            {
                switch(column_count)
                {
                case 1:
                    {
                        std::stringstream temp_cell[2];
                        std::string li;
                        std::stringstream streamcell;
                        streamcell << cell;

                        for(unsigned i = 0; i < 2; i++)
                        {
                            getline(streamcell, li, ' ');
                            temp_cell[i] << li;
                        }
                        temp_cell[0] >> temp_d;
                        temp_cell[1] >> temp_t;
                        w.SetDate(temp_d);
                        w.SetTime(temp_t);
                        break;
                    }
                case 11:
                {
                    std::stringstream iss;
                    iss << cell;
                    iss >> temp_s;
                    w.SetSpeed(temp_s);
                    break;
                }
                case 12:
                {
                    std::stringstream iss;
                    iss << cell;
                    iss >> temp_rad;
                    w.SetRad(temp_rad);
                    break;
                }
                case 18:
                {
                    std::stringstream iss;
                    iss << cell;
                    iss >> temp_air;
                    w.SetAir(temp_air);
                    break;
                }
            }
        }
    }
}
    w.SetCounter(row_count);
}


Moreover, I am saving each Class in a Vector class did I was supposed to do.

If you wanna see, this is my Vector class:

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
#ifndef VECTOR_H
#define VECTOR_H

#include <vector>

template <class T>
class Vector
{
public:
    Vector();
    ~Vector();
    void add(T& obj);                //addition function, it will add elements in the array
    T getAt(unsigned index) const;   //template function to return a element given a certain index

private:
    int cap;             //capacity integer, it will be resized and changed later
    int nEl;             //number of elements integer, it will check if the cap has been reached
    std::vector<T> arr;  //pointer template
};

template <class T>
Vector<T>::Vector()
{
    this->cap = 500;
    this->nEl = 0;
}

template <class T>
Vector<T>::~Vector()
{

}

template <class T>
void Vector<T>::add(T& obj)
{
    this->arr.push_back(obj);
}

template <class T>
T Vector<T>::getAt(unsigned index) const
{
    return this->arr[index];
}

#endif // VECTOR_H 

Last edited on
Moreover, I am saving each Class in a Vector class


Where?

At the moment you are reading each file successively into the same Windlog object.


Also, why don't you use std::vector instead of creating your own?
Last edited on
This is a task for uni. My teacher wasn't allowing us to use STL Vector, so we needed to create our own template vector class. Now, I think I can use STL Vectors, but I think this code should read those files using this Vector Class.

Where?

At the moment you are reading each file successively into the same Windlog object.


WindLog creates a vector object of each class. For instance:

1
2
3
4
5
6
7
8
private:
    Vector<Date> dates;            //Date vector object
    Vector<Time> times;            //Time vector object
    Vector<WindSpeed> speeds;      //Wind speed vector object
    Vector<SolarRadiation> rad;    //Solar radiation vector object
    Vector<AirTemperature> airT;   //Air temperature vector object
    int counter;                   //Counter integer to get number of elements
};


This is from my WindLog.h header file.

Therefore, I have a bunch of setters and getters and each setter is setting for a Vector.

For example:

1
2
3
4
void WindLog::SetDate(Date d)
{
    dates.add(d);
}
Last edited on
Wouldn't it be easier to have a std::vector<Windlog>, where a Windlog is a struct or class containing scalar objects:
1
2
3
4
5
6
7
8
struct Windlog
{
   Date date;
   Time time;
   double speed;
   double rad;
   double airT;
};


Also, there is nothing in the code you have shown that would allow you to know whether you have read all the files or not. Your Vector class is a bit unnecessary. You are just wrapping a std::vector.

I would refactor your code.

Last edited on
I've just changed the objects trying to use STL Vector and it is still only reading the first CSV File. Alright, I will follow your advise and try to refactor it. Thanks so much for your help! Appreciate it!
Topic archived. No new replies allowed.