C++, write from file into map - c++

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))

Related

C++ CSV Getline

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();
}

How to read content of the file and save it to string type variable? Why there is empty space?

This is how I get the name of the file from the command line and open a file and save the content of the file line by line to a string. All the procedures works fine except three empty spaces at the beginning of the file. Is anyone can say why these empty spaces occurred and how can I ignore them?
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
if(!fin.good()){
cout<<" = File does not exist ->> No File for reading\n";
exit(1);
}
string s;
while(!fin.eof()){
string tmp;
getline(fin,tmp);
s.append(tmp);
if(s[s.size()-1] == '.')
{
//Do nothing
}
else
{
s.append(" ");
}
cout<<s<<endl;
The most probable cause is that your file is encoded in something else than ASCII. It contains a bunch of unprintable bytes and the string you on the screen is the result of your terminal interpreting those bytes. To confirm this, print the size of s after the reading is done. It should be larger than the number of characters you see on the screen.
Other issues:
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
is quite an overzealous way to go about it. Just write ifstream fin(a.c_str());, or simply ifstream fin(a); in C++11.
Next,
while(!fin.eof()){
is almost surely a bug. eof() does not tell if you the next read will succeed, only whether the last one reached eof or not. Using it this way will tipically result in last line seemingly being read twice.
Always, always, check for success of a read operation before you use the result. That's idiomatically done by putting getline in the loop condition: while (getline(fin, tmp))

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().

Missing line of data using Getline with Ifstream

Ok so this is killing me at the moment cause its such a simple part of my program that just doesn't want to work. I'm reading data from a textfile to use in a GA.
The first getline() works perfectly, but the second one doesn't want to write any data into my string. When i cout the string it doesn't show anything.
Here is the code:
ifstream inFile;
inFile.open(fname.c_str());
char pop[20], mut[20];
inFile.getline(pop,20);
cout << pop;
inFile.getline(mut,20);
cout << mut; //this outputs nothing
Thanks for any help in advance.
A sample form my file:
there is no line between them mutation is the line straight after population
Population size: 30
Mutation: 20
Your file's first line is 20 characters long (19+new line) but pop[20] can only contain 19 (because the last one is reserved for the null terminator '\0').
When istream::getline stops because it has extracted 20-1 characters, it doesn't discard the new line delimiter (because it was never read). So the next getline just reads the end of the first line, discarding the new line.
That's why you get nothing in the second string.
Your problem is that the length of your input line exceeds the length of the buffer which must hold it.
The solution is to not use character arrays. This is C++, use std::string!
std::ifstream inFile;
inFile.open(fname.c_str());
std::string pop;
std::getline(inFile, pop);
cout << pop << "\n";
std::string mut;
std::getline(inFile, mut);
cout << mut << "\n";
I think you need to find out what the problem is. Add error checking code to your getline calls, refactor the (simple) code into a (simple) function, with a (simple) unittest. Possibly, your second line is longer than the assumed 20 characters (null-term included!).
For an idea of what I mean, take a look at this snippet.
try something like
while (getline(in,line,'\n')){
//do something with line
}
or try something like
string text;
string temp;
ifstream file;
file.open ("test_text.txt");
while (!file.eof())
{
getline (file, temp);
text.append (temp); // Added this line
}

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.