I'm trying to read in a .csv file that looks like this:
Name,Place,Age,x,y
A,X,1,50,100
B,Y,2,-90,20
C,Z,3,0.4,80
...
Except there are 100 rows of data (plus the header).
I would like to read in the columns Name, Age, x and y and place them in an vector that looks like this:
Name = [Age, x, y]
and do this for all 100 rows (so 100 vectors).
I've tried searching the forum for help but the best help I could get was from c++ Skip first line of csv file , which I modified slightly just to print the Age, x, y.
ifstream data("data.csv");
if (!data.is_open())
{
exit(EXIT_FAILURE);
}
string str;
getline(data, str); // skip the first line
while (getline(data, str))
{
istringstream iss(str);
string token;
while (getline(iss, token, ','))
{
double Age_x_y = atof(token.c_str());
if (Age_x_y != 0) {
cout << Age_x_y << " ";
}
cout << endl;
}
}
This is nice if it was all I wanted to output, but I believe all the data is just stored as a double. I need the data stored in a vector (or something else like a structure) so that I can manipulate the entries. For example, I would like to work out x+y for each Name.
How can I extract the data in this way?
Any help would be greatly appreciated.
Your parsing of the CSV is good, but be careful that you don't provide any data where the fields have embedded commas. Some CSV formatters allow a field to contain a comma if the field is enclosed in double-quotes for example.
You can create a structure which represents (more or less) a single line in your CSV file.
struct Record
{
std::string name;
std::string place;
int age;
double x;
double y;
};
Now, you can parse each line into a Record object (pick an appropriate name for the struct), and then place each Record into a vector. Make sure to include <string> and <vector>.
std::vector<Record> my_records;
while (getline(data, str))
{
Record record;
istringstream iss(str);
string token;
getline(iss, record.name, ',');
getline(iss, record.place, ',');
// use atoi(token.c_str()) if you don't have std::stoi from C++11
getline(iss, token, ',');
record.age = std::stoi(token);
// use atof(token.c_str()) if you don't have std::stod from C++11
getline(iss, token, ',');
record.x = std::stod(token);
getline(iss, token, ',');
record.y = std::stod(token);
my_records.push_back(record);
}
// loop through the vector, summing every possible
// combination of x values. The outer loop goes from
// index 0 to the second-to-last index, while the inner
// loop goes from the current outer loop counter to the
// last index.
// Note that this is O(n^2) complexity (even with a
// diminishing inner loop). Increasing the number of
// records can have a very noticeable effect on running
// time.
for (size_t i = 0; i < my_records.size() - 1; i++)
{
for (size_t j = i + 1; j < m_records.size(); j++)
{
std::cout << my_records[i].name << ".x + ";
std::cout << my_records[j].name << ".x = ";
std::cout << (my_records[i].x + my_records[j].x) << std::endl;
}
}
You can also use my_records[i].x + my_records[i].y if you want to output the sum of those values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With