Reputation: 43
I am new in C++, actually learning to do the assignments from the Masters I am studying.
Firstly in my code, I need to read each row and column from a csv file and store it in an array[][].
My CSV file is(columns A1, A2, B1, B2):
46842 test
46825 test2
My code atm is:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
string val;
string arr[2][2];
ifstream myFile;
myFile.open("excel.csv");
while (myFile.good())
{
for(int row = 0; row <= 1; row++)
{
for(int column = 0; column <= 1; column++)
{
getline(myFile, val, ',');
arr[row][column] = val;
}
}
}
cout <<"cell 0.0: " << arr[0][0] << endl;
cout <<"cell 0.1: " << arr[0][1] << endl;
cout <<"cell 1.0: " << arr[1][0] << endl;
cout <<"cell 1.1: " << arr[1][1] << endl;
}
The problem is the outcome:
cell 0.0: 46842 cell 0.1: test 46825 cell 1.0: test2 cell 1.1: test2
It should be:
cell 0.0: 46842 cell 0.1: test cell 1.0: 46825 cell 1.1: test2
it seems like the problem is when it reaches the last position of the first row. Does anyone know how to fix this? Thanks :)
Upvotes: 0
Views: 70
Reputation: 15267
You made some mistakes that need to be fixed. You used std::getline
to read until the next comma. It will do exactly that, even if a new line starts. So it will continue tor read until it finds the next comma. This will explain the output of
cell 0.1: test
46825
It shows "test", then the new line and then 46825.
So, this will not work. We need to use a line based approach. We will first read a complete line 46842,test
and then split it. We will use std::getline
to split it. But now, it will work, becuase it will extract data until the next comma or until the end of the line.
You should also never use:
while (myFile.good())
Please see 3 possible solutions:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string val;
string arr[2][2];
ifstream myFile;
myFile.open("excel.csv");
int row = 0;
while (getline(myFile,val))
{
std::istringstream iss(val);
for (int column = 0; column <= 1; column++)
{
getline(iss, arr[row][column], ',');
}
++row;
}
cout << "cell 0.0: " << arr[0][0] << endl;
cout << "cell 0.1: " << arr[0][1] << endl;
cout << "cell 1.0: " << arr[1][0] << endl;
cout << "cell 1.1: " << arr[1][1] << endl;
}
Next improvement
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
int main() {
std::string val;
std::string arr[2][2];
std::ifstream myFile;
myFile.open("excel.csv");
for (unsigned int row = 0; std::getline(myFile, val); ++row)
{
std::istringstream iss(val);
for (unsigned int column = 0; column <= 1; column++)
{
std::getline(iss, arr[row][column], ',');
}
}
std::cout << "cell 0.0: " << arr[0][0] << std::endl;
std::cout << "cell 0.1: " << arr[0][1] << std::endl;
std::cout << "cell 1.0: " << arr[1][0] << std::endl;
std::cout << "cell 1.1: " << arr[1][1] << std::endl;
}
Full C++ solution:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
int main() {
// Here we will store all data from our CSV file
std::vector<std::vector<std::string>> data{};
// Open the csv file with the source data
std::ifstream myFile{ "excel.csv" };
// Check, if we could open the source file
if (myFile) {
// We will read all lines of the source file in a for loop
for (std::string line{}; std::getline(myFile, line); ) {
// Stuff the line in an std::istringstream, so that we can extract data of jkust one line
std::istringstream lineAsStream{ line };
// The single parts of one line
std::vector<std::string> parts{};
for (std::string partData{}; std::getline(lineAsStream, partData, ','); parts.push_back(partData))
; // Empty body
// Store new row data
data.push_back(parts);
}
std::cout << "cell 0.0: " << data[0][0] << std::endl;
std::cout << "cell 0.1: " << data[0][1] << std::endl;
std::cout << "cell 1.0: " << data[1][0] << std::endl;
std::cout << "cell 1.1: " << data[1][1] << std::endl;
}
else {
std::cerr << "\n***Error: COuld not open source file\n";
}
return 0;
}
Upvotes: 1
Reputation: 43
This is my code atm. it prints:
cell 0.0: 46842
cell 0.1: test
cell 1.0: 46842
cell 1.1: test
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
main() {
string arr[2][2];
string val;
string my_str;
ifstream myFile;
myFile.open("excel.csv");
for(int row = 0; row <= 1; row++) {
getline(myFile, val);
stringstream s_stream(val);
for(int column = 0; column <= 1; column++) {
string substr;
getline(s_stream, substr, ',');
result.push_back(substr);
arr[row][column] = result.at(column);
}
}
cout <<"cell 0.0: " << arr[0][0] << endl;
cout <<"cell 0.1: " << arr[0][1] << endl;
cout <<"cell 1.0: " << arr[1][0] << endl;
cout <<"cell 1.1: " << arr[1][1] << endl;
}
Upvotes: 0