C++ CSV Getline - c++

I have one column of floats in a csv file. No column header.
string val;
vector<float> array;
string file = "C:/path/test.csv";
ifstream csv(file);
if (csv.is_open())
{
string line;
getline(csv, line);
while (!csv.eof())
{
getline(csv, val, '\n');
array.push_back(stof(val));
}
csv.close();
}
I want to push the values in the column to vector array. When I use ',' as a delimiter it pushes the first line to the array but the rest of the column gets stuck together and unpushable. If I use '\n' it doesn't return the first line and I get a stof error.
I tried other answers unsuccessfully. What is the correct way to format this here?
test.csv

Your raw test.csv probably looks like this:
1.41286
1.425
1.49214
...
So there are no comma's, and using , as '(line) separator' would read the whole file and only parse the first float (up to the first \n).
Also, the first line is read but never used:
getline(csv, line); // <- first line never used
while (!csv.eof())
{
getline(csv, val, '\n');
array.push_back(stof(val));
}
Since there is only one field you don't have to use a separator and, as already mentioned in the comments, using while(getline(...)) is the right way to do this:
if (csv.is_open())
{
string line;
while (getline(..))
{
array.push_back(stof(val));
}
csv.close();
}

Related

C++, write from file into map

im just new at c++ and I try to read from a file and write the content into a map<string, float>.
But only the first element of my file gets mapped and i cant figuer out why.
The file looks like this:
E:16.93
N:10.53
I:8.02
...
And the code i got for this part so far:
std::map<char, float> frequenciesM;
fstream frequencieFile("frequencies.txt", std::ios::in);
if(!frequencieFile){
cout << "No such File!";
}else{
std::string line;
char ch;
std::string sub;
float fl;
while (std::getline(frequencieFile, line, '\0')) {
ch = line[0];
sub = line.substr(2);
fl = std::stof(sub);
frequenciesM[ch] = fl;
}
}
When i try to print out the size and content of my map, this is what i get:
Size: 1
E: 16.93
Thx for any help and suggestions!
You are telling getline() to read until a '\0' (nul) character is encountered, but there is no such character in your file, so the entire file gets read into the string on the 1st call, and then you extract only the 1st set of values from the string, discarding the rest of the data.
To read the file line-by-line, you need to change the 3rd parameter of getline() to '\n' instead:
while (std::getline(frequencieFile, line, '\n'))
Or, just drop the 3rd parameter entirely since '\n' is the default delimiter:
while (std::getline(frequencieFile, line))

ifstream from next/new line in c++

I am having set of data stored in a file which are basically names. My task is to get all the first letters from each name. Here is the file:
Jack fisher
goldi jones
Kane Williamson
Steaven Smith
I want to take out just first word from each line(ex. jack, goldi, kane, Steaven)
I wrote following code for it, just to take take out 2 names. Here it is:
string first,last;
ifstream Name_file("names.txt");
Name_file>>first;
Name_file>>endl;
Name_file>>last;
cout<<first<<" "<<last;
it is giving error. If I remove endl, it takes the first full name(Jack, fisher) whereas I want it should take (jack ,goldi). How to do it ? Any idea? Thanks in advance for help.
Name_file>>endl; is always wrong.
Even then, you can't use >> like that, it will stop on a space, which is why when you remove endl you see the problem that first and last contain only the first line.
Use std::getline to loop over your file instead and get the full names, then split the line on the first space to get the first name:
ifstream Name_file("names.txt");
std::string line;
while (std::getline(Name_file, line))
{
std::string firstName = line.substr(0, line.find(' '));
//do stuff with firstName..
}
Though I don't mind "Hatted Rooster"implementation I think it can be a little less efficient when the input suddenly contains a very long line.
I would use ignore() to remove the rest of the line:
int main()
{
std::ifstream nameFile("names.txt");
std::string firstName;
while (nameFile >> firstName)
{
// You got a first name.
// Now dump the remaing part of the line.
nameFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
I hope this solves your query.
ifstream Name_file;
string line;
Name_file.open("names.txt");
if(Name_file.fail()){ cerr<<"Error opening file names.txt !!"<<endl;return;}
vector<string> v; // array to store file names;
while(Name_file >> line){
string word;
getline(Name_file, word);
v.push_back(line);
}
// printing the first names
for(int i = 0; i < v.size();i++){
cout<<v[i]<<endl;
}

C++ : Reading file and store data in multi-vector

I am trying to read data file with the this format
T1: I1,I2,I5
T2: I2,I4
T3: I2,I3
T4: I1,I2,I4
T5: I1,I3
T6: I2,I3
T7: I1,I3
T8: I1,I2,I3,I5
T9: I1,I2,I3
I don't want to read the first column T1,T2,T3 ...... , but each line will be a dataset I want to start read after (space ' ' ) and end with each line and how can I separate the data according to (comma ',')
I wrote this code but it didn't work correctly and it reads the first column anyway
string CItem;
// set of elements
set< CItem > CItemSet;
//Transactions
CItemSet CTransaction;
// set of transactions
vector< CTransaction > CTransactionSet;
ifstream inFile(inFileName);
if (!inFile)
{
cout << "Failed to open input file filename:." << inFileName;
}
CTransactionSet transSet;
CTransaction tran;
string txtLine;
// read every line from the stream
while (getline(inFile, txtLine))
{
istringstream txtStream(txtLine);
string txtElement;
// read every element from the line that is seperated by commas
// and put it into the vector or strings
while (getline(txtStream, txtElement, ','))
{
if (txtElement == ": ") break;
else tran.insert(txtElement);
}
transSet.push_back(tran);
}
Since you have
CTransaction tran;
outside the first while loop, items keep getting added to it. Move it inside the while loop.
CTransactionSet transSet;
string txtLine;
// read every line from the stream
while (getline(inFile, txtLine))
{
CTransaction tran;
I solve the problem by doing what you said R Sahu but the most important solution is by using .ignore so we don't read the part before the ' '
CTransactionSet transSet;
string txtLine;
// read every line from the stream
while (getline(inFile, txtLine))
{
istringstream txtStream(txtLine);
txtStream.ignore(txtLine.length(), ' ');
// read every element from the line that is seperated by commas
// and put it into the vector or strings
string txtElement;
CTransaction tran;
while (getline(txtStream, txtElement, ','))
{
tran.insert(txtElement);
}
transSet.push_back(tran);
}

ifstream get line change output from char to string

C++ ifstream get line change getline output from char to string
I got a text file.. so i read it and i do something like
char data[50];
readFile.open(filename.c_str());
while(readFile.good())
{
readFile.getline(data,50,',');
cout << data << endl;
}
My question is instead of creating a char with size 50 by the variable name data, can i get the getline to a string instead something like
string myData;
readFile.getline(myData,',');
My text file is something like this
Line2D, [3,2]
Line3D, [7,2,3]
I tried and the compiler say..
no matching function for getline(std::string&,char)
so is it possible to still break by delimiter, assign value to a string instead of a char.
Updates:
Using
while (std::getline(readFile, line))
{
std::cout << line << std::endl;
}
IT read line by line, but i wanna break the string into several delimiter, originally if using char i will specify the delimiter as the 3rd element which is
readFile.getline(data,50,',');
how do i do with string if i break /explode with delimiter comma , the one above. in line by line
Use std::getline():
std::string line;
while (std::getline(readFile, line, ','))
{
std::cout << line << std::endl;
}
Always check the result of read operations immediately otherwise the code will attempt to process the result of a failed read, as is the case with the posted code.
Though it is possible to specify a different delimiter in getline() it could mistakenly process two invalid lines as a single valid line. Recommend retrieving each line in full and then split the line. A useful utility for splitting lines is boost::split().

trying to read a text file data into an array to be manipulated then spit back out

My aim is to take the data from the file, split it up and place them into an array for future modification.
The is what the data looks like:
course1-Maths|course1-3215|number-3|professor-Mark
sam|scott|12|H|3.4|1/11/1991|3/15/2012
john|rummer|12|A|3|1/11/1982|7/15/2004
sammy|brown|12|C|2.4|1/11/1991|4/12/2006
end_Roster1|
I want to take maths, 3215, 3 and Mark and put into an array,
then sam scott 12 H 3.4 1/11/1991 3/15/2012.
This is what I have so far:
infile.open("file.txt", fstream::in | fstream::out | fstream::app);
while(!infile.eof())
{
while ( getline(infile, line, '-') )
{
if ( getline(infile, line, '|') )
{
r = new data;
r->setRcourse_name(line);
r->setRcourse_code(3);//error not a string
r->setRcredit(3);//error not a string pre filled
r->setRinstructor(line);
cout << line << endl;
}
}
}
Then I tried to view it nothing is stored.
Firstly line 1 is very different to the remaining lines so you need a different parsing algorithm for them. Something like:
bool first = true;
while(!infile.eof())
{
if (first)
{
// read header line
first = false;
}
else
{
// read lines 2..n
}
}
Reading lines 2..n can be handled by making a stringstream for each line, then passing that in to another getline using '|' as a delimeter, to get each token (sam, scott, 12, H, 3.4, 1/11/1991, 3/15/2012)
if (getline(infile, line, '\n'))
{
stringstream ssline(line);
string token;
while (getline(ssline, token, '|'))
vector.push_back(token);
}
Reading the header line takes the exact same concept one step further where each token is then further parsed with another getline with '-' as a delimiter. You'll ignore each time the first tokens (course1, course1, number, professor) and use the second tokens (Maths, 3215, 3, Mark).
You are completely ignoring the line that you get inside the condition of the nested while loop. You should call getline from a single spot in your while loop, and then examine its content using a sequence of if-then-else conditions.