C++ 2D Vector from a csv file - c++

I have this .csv file. It has 6 columns (separated by comma) and many rows. I want to make a 3D vector such that each row is in a vector and all rows are inside the 3D vector.
My code so far:
// open a file in read mode.
ifstream csv("test.csv");
string line;
vector <string> lineV;
if (csv.is_open()) {
for (int i = 0; csv.good(); i++)
{
getline(csv, line, ',');
lineV.push_back(line);
}
}
else {
cout << "Unable to open file";
}
// close the opened file.
csv.close();
Now, I have this vector lineV which has all the values in the .csv file separated by commas, like this:
row1column1
row1column2
row1column3
row1column4
row1column5
row1column6
row2column1
...and so on
I thought of trying to iterate through the vector and passing the values to a new vector after every 6th value, but I don't know how to start.
Alternatively, if I change getline(csv, line, ','); to getline(csv, line);, I can get it row by row:
row1column1,row1column2,row1column3,row1column4,row1column5,row1column6
row2column1,row2column2,row2column3,row2column4,row2column5,row2column6
...and so on
But I will still have to split each row to its own vector...

It may be easier for you to read the csv file by lines first (rows), then use a std::istringstream to extract comma separated entities from each line.
// open a file in read mode.
std::ifstream csv("test.csv");
std::string line;
std::vector <std::vector<std::string>> items;
if (csv.is_open()) {
for (std::string row_line; std::getline(csv, row_line);)
{
items.emplace_back();
std::istringstream row_stream(row_line);
for(std::string column; std::getline(row_stream, column, ',');)
items.back().push_back(column);
}
}
else {
cout << "Unable to open file";
}

Related

How do i read a csv text file into a 2D array?

This is the sample text file content:
5 //columns
Id,Age,history,chemistry,biology //column names
100// number of data rows
3245167,12,45,78,12 //data rows separated by commas
30980424,10,26,38,98
and so on..
This is the general code i have so far:
int main()
{
//prints out input from file.
ifstream myFile;
myFile.open("WRITE FILE NAME");
while(Myfile.good()) { // good means while there is smthg in the file keep reading it
// until you reach to the end.
string line;
getline(myFile, line, ','); //read text until comma, then stop and store in variable.
cout << line << endl;
}
return 0;
}
You have a general outline of parsing the file itself, the data will be read from the file left to right. So there's two things I'd recommend for you to do at this point since you've already parsed the data. You'll probably want something to hold it like a queue to store and hold all the data and a double for loop to place it into the 2D array so like this:
std::queue<string> holder;
std::string myArray[row][col];
getline(myFile, line, ',');
holder.push(line);
for(int i=0; i < row; i++)
{
for(int j=0; j < col; j++)
{
myArray[i][j] = holder.pop();
}
}

formatting strings in a .txt file (C++)

unformatted_grades.txt:
formatted_grades.txt:
I am working on an assignment where my professor wants me to open and read a .txt file with different strings inside of it. We are supposed to format the content of the file.
Ex:
The read_grade_file method has a parameter int number_of_students
The first line of the file is "number_of_students 9"
I have opened and read the file and pushed each individual line into a string vector.
How do I get the number 9 in the first line by itself so I can make the number_of_students parameter equal to it???
Please help.
(We are allowed to skip over or delete any irrelevant data from the vector).
My code:
void Read_Grade_File(string names[MAX_CLASS_SIZE][2], int scores[MAX_CLASS_SIZE][MAX_NUMBER_OF_ASSIGNMENTS], int *number_of_students, int *number_of_assignments, const string input_filename) {
string currline; // temporarily holds the content of each line read from the file
ifstream inFile; // filestream
vector<string> content; // vector containing each string from the file
inFile.open(input_filename); //open the file.
if (inFile.is_open()){
// reads file and pushes the content into a vector
while(!inFile.eof()){
getline(inFile, currline);
if(currline.size() > 0){
content.push_back(currline);
}
}
}
// prints the content stored in the vector
for (int i = 0; i < content.size(); i++){
cout << content[i] << endl;
}
}
Rather than reading the entire line at once, it may make more sense to read the various values on the line as you go. For example, if you know the format of the file, then you can read the first variable's name followed by reading the value of the variable like this:
std::string variableName;
int variableValue;
inFile >> variableName;
inFile >> variableValue;
So you could get the variables whose names you know, find their values, and then loop through the rest of the file reading in that many records.

could'nt read correct values of vector produced from file

I am trying to read text file line by line and then read each column as vector but when i am tryin to cout first column it shows zeros i.e. not reading the file correctly.
int main(void)
{
ifstream myfile ("data1.txt");
string line;
if (myfile.is_open())
{
int ln=1;
while ( getline (myfile,line) )
{
if(ln==1){ln++; continue;}
istringstream iss(line);
string word;
vector<double> column;
int w=1;
while(iss >> word)
{
//double dw=atof(Form("%s",word));
column.push_back(atof(Form("%s",word)));
cout<<column[0];
w++;
}
ln++;
cout<<"\n";
}
myfile.close();
}
//else
else cout<<"Unable to open file";
cout<<"\n";
return ;
}enter code here
push_back appends an element as last element of the vector while columns[0] always refers to the first element of the vector.
Is the first element 0
Is there another problem?
(Please explain what is Form, give an example of input file and output in the command line)
First of all learn how to indent and consistently use some scheme for inserting blank lines that makes sense. When you do that you can read your own code and figure out if it is doing what you think it is.
Second. Save Form("%s",word) in a string ( for now call it form_string) add this line cout<<"form returns "<<form_string<<endl; 99.99% probably it will print zeros.
Finally change: cout<<column[0]; to cout<<column[0]<<" "; or cout<<*(column.rbegin())<<" ";. The latter prints out all the values that you read, the former prints out the first value you read over and over.

Reading separated columns in a CSV file in C++ using getLine

I have a program that can successfully read a CSV file. The said CSV file is a list separated by 3 columns. And each column has a comma in between each line. For instance
line 1 --- artist, genre, song
line 2 --- Michael jackson, Pop, thriller
and so on. What I want my program to do is read the first line and to take artist, genre, and song, print those out to the user as options. For instance
"Choose an Option"
1. Artist
2. Genre
3. Song
and then when they select an option it then shows them either all the artists, songs, or genres in the CSV file.
So far I have my program reading the CSV and putting each line in a vector. Here is my code so far ...
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
ifstream infile("music_list.csv");
string line = "";
vector<string> all_words;
cout << "Hello";
while (getline(infile, line))
{
stringstream strstr(line);
string word = "";
while (getline(strstr,word, ','))
{
all_words.push_back(word);
}
for (unsigned i = 0; i < all_words.size(); i++)
{
cout << all_words.at(i)<< "\n";
}
}
system("pause");
return 0;
}
I'm just having trouble figuring out how to have it read the first line, separate each string in the first line that is already separated by a comma and have that then outputted to the user as an option. So in essence I can change artist, genre, song to something like appetizers, dish, drinks in the CSV file.
First you have to read the csv file and store the lines in a vector, You can use this function to do that.
vector<string> readCsvFileContent(const string file)
{
vector<string> buffer;
ifstream configFile;
configFile.exceptions(ifstream::badbit);
try
{
configFile.open(file.c_str(),ifstream::in);
if(configFile.is_open())
{
string line;
while (getline(configFile,line))
{
buffer.push_back(line);
}
configFile.close();
}
}
catch (ifstream::failure e){
throw e;
}
return buffer;
}
Then split the each line entry to 2D vector. for that you can use this function
vector<vector<string>> processCsvList(vector<string> csvList)
{
#define SINGER_CONFIG_COUNT 3 //number of comma separated data suppose to be in one line.
#define DELIMITED_CHAR ","
#define EMPTY_STRING "";
vector<vector<string>> tempList;
string configCell ="";
for(vector<string>::iterator it = csvList.begin(); it != csvList.end(); ++it)
{
if(*it == EMPTY_STRING)
{
continue;
}
stringstream configLine(*it);
vector<string> tempDevice;
for(int i=0; i<SINGER_CONFIG_COUNT; i++)
{
if(getline(configLine,configCell,DELIMITED_CHAR))
{
tempDevice.push_back(configCell);
}else
{
tempDevice.push_back(EMPTY_STRING);
}
}
tempList.push_back(tempDevice);
}
return tempList;
}
I haven't try to compile any of these function, because I do not have environment to do so here. But I think this will help to to think about the direction.
now your data in a 2D vector like excell sheet. So you can access by the index of the inner vector.
You could create a std::map<string,vector<string>> so that you could then store each column of the CSV file from line 2 onwards in the map as a vector of strings, keyed by the text that appears in the column on line 1 of the CSV file.
Then you could present the names of the fields by iterating through the keys of the std::map, which are conveniently stored in alphabetical order.
The task of reading in the first line of the CSV file could be performed by the code you already have, or something more sophisticated that takes into account the quoted fields, etc. that are found in fully-featured CSV files.

Best method for reading row and col of txt file

Sorry, im a C++ noob! I have looked around for a solution but cant seem to find one that best suits my need. I am tring to read the width(max amount of char in line) and height (max amount of lines per file) of a txt file. Planning on using varaibles to help make dynamic sized txt files/levels.
I have had fixed width and height working previous to this!
TXT FILE: Simple output of chars for room layout (space=floor, #=wall, X=door):
########
# #
# X
# #
########
PROBLEM: Thought this to be a simple problem, but it only reads 2 of each variable(hNum,wNum)before breaking loop and program cant continue.
-What am i doing wrong?
-Should i be using seekg or different loop somehow?
-Do i need to alter my vector to 2D vector?
-Which is the best method for achieving this?
Room.cpp
//LOAD CURRENT ROOM FROM FILE
ss << RoomNo;
string str = ss.str();
string fname = ("Room");
fname.append(str);
fname.append(".txt");
infile.open(fname);
infile.clear();
infile.seekg(0);
if(infile.is_open())
{
// Sets width and height depndant on txt file size
string line;
//NOT WORKING!
while( !infile.eof())
{
hNum++;
getline ( infile, line);
wNum += line.length();
break;
}
height=hNum;
width=wNum;
//END
// Loop to end of file- to get you all the lines from txt file.
while(!infile.eof())
{
int i;
for(int row = 0; row < width; row++)
{
infile.getline(RoomFile, 256);
i = 0;
for(int col = 0; col < height; col++)
{
data.push_back(RoomFile[i]);
i++;
}
}
}
}
else
{
cout << "ERROR: infile not open" << endl;
}
infile.close();
UPDATE
This is what i got, tryin to do what Sky suggested...but cudnt work it all out. Then steped thro and thought the loop wasnt active so altered the argument. Now getting runtime error!
PROBLEM: Expression: vector subscript out of range!
Suggestions anyone?
string line;
while(getline(infile,line))
{
getline(infile, line);
tempVector.push_back(line);
}
width=line.length();
height=tempVector.size();
A possible way that can work would be to create a vector of strings and read the entire file, with each line a string in the vector.
Rough example:
#include <vector>
#include <string>
#include <fstream>
/* ... */
vector<string> content;
string buffer;
while(!infile.eof())
{
getline(infile, &string, '/n');
content.push_back(string);
}
width = findMaxLengthOfStrings(content);
height = content.size();
You are reading each line of the file as a separate string. The strings are pushed onto the vector. You can then easily find which string in the vector is longest, by iterating through the vector, using size(). The length in lines of the file is obtained with size() on the vector itself.
Also, posting just the relevant parts of the code, the I/O function, would have helped. Just saying ;) A small screen size and such.