How to skip a line of a file if it starts with # in c++ - c++

So say I have a txt file that goes like:
#unwanted line
something=another thing
something2=another thing 2
#unwanted_line_2=unwanted
something3=another thing 3
and I am reading it with
getline(inFile,astring,'=');
to separate a something from its value (inside a while loop). How do I skip the entire lines that start with # ?
Also I'm storing this in a vector, if it is of any matter.

Use getline() without a delimiter to read an entire line up to \n. Then check if the line begins with #, and if so then discard it and move on. Otherwise, put the string into an istringstream and use getline() with '=' as the delimiter to split the line (or, just use astring.find() and astring.substr() instead).
For example:
while (getline(inFile, astring))
{
if (!asstring.empty() && astring[0] != '#')
{
istringstream iss(astring);
getline(iss, aname, '=');
getline(iss, avalue);
...
}
}

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

C++: Using getline to input from a text file either skips the first line or messes up the rest

I'm trying to read in from a specially formatted text file to search for specific names, numbers, etc. In this case I want to read the first number, then get the name, then move on to the next line. My problem seems to be with while loop condition for reading through the file line by line. Here is a sample of the txt file format:
5-Jon-4-Vegetable Pot Pie-398-22-31-Tue May 07 15:30:22
8-Robb-9-Pesto Pasta Salad-143-27-22-Tue May 07 15:30:28
1-Ned-4-Vegetable Pot Pie-398-22-31-Tue May 07 15:30:33
I'll show you two solutions I've tried, one that skips the first line in the file and one that doesn't take in the very last line. I've tried the typical while(!iFile.eof()) as a last ditch effort but got nothing.
transactionLog.clear();
transactionLog.seekg(0, std::ios::beg);
std::string currentName, line, tempString1, tempString2;
int restNum, mealNum;
bool nameFound = false;
int mealCount[NUMMEALS];
std::ifstream in("patronlog.txt");
while(getline(in, line))
{
getline(in, tempString1, '-');
getline(in, currentName, '-');
if(currentName == targetName)
{
if(getline(in, tempString2, '-'))
{
mealNum = std::stoi(tempString2);
mealCount[mealNum - 1] += 1;
nameFound = true;
}
}
I believe I understand what's going in this one. The "getline(in, line)" is taking in the first line entirely, and since I'm not using it, it's essentially being skipped. At the very least, it's taking in the first number, followed by the name, and then doing the operations correctly. The following is the modification to the code that I thought would fix this.
while(getline(in, tempString1, '-'))
{
getline(in, currentName, '-');
// same code past here
}
I figured changing the while loop condition to the actual getline of the first item in the text file would work, but now when I look at it through the debugger, on the second loop it sets tempString1 to "Vegetable Pot Pie" rather than the next name on the next line. Ironically though this one does fine on line #1, but not for the rest of the list. Overall I feel like this has gotten me farther from my intended behavior than before.
You need to parse the contents of lines after they are read. You can use a std::istringstream to help you with that.
while(getline(in, line))
{
// At this point, the varible line contains the entire line.
// Use a std::istringstream to parse its contents.
std::istringstream istr(line);
getline(istr, tempString1, '-'); // Use istr, not in.
getline(istr, currentName, '-'); // ditto
...
}

What types of indicators are there for the end of a string when tokenizing a sentence?

I am trying to take a string holding a sentence and break it up by words to add to a linked list class called wordList.
When dealing with strings in C++, what is the indicator that you have reached the end of a string? Searched here are found that c strings are null terminated and some are indicated with a '\0' but these solutions give me errors.
I know there are other ways to do this (like scanning through individual characters) but I am fuzzy on how to implement.
void lineScan( string line) // Adds words to wordList from line of a file
{
istringstream iss(line);
string lineWord;
getline(iss, lineWord, ' ');
wrds.addWords( lineWord );
while( lineWord!= NULL )
{
getline(iss, lineWord, ' ');
wrds.addWords( lineWord );
}
}
You probably want to skip all whitespace, not use a single space as separator (your code will read empty tokens).
But you're not really dealing with strings here, and in particular not with C strings.
Since you're using istringstream, you're looking for the end of a stream, and it works like all instreams.
void lineScan(string line) // Adds words to wordList from line of a file
{
istringstream iss(line);
string word;
while (iss >> word)
{
wrds.addWords(word);
}
}

How to detect the end of a line from a file stream in C++

I have csv file input where I read in multiple lines which contain multiple fields related to that line. How do I write a loop which reads a line of text from the csv file, then keeps looping until it reaches the end of that line. This while loop would be nested in an !infile.eof while loop. Here is what I has so far but doesn't work exactly.
while (getline(infile, currentline))
{
getline(infile, ID, ',');
getline(infile, Name, ';');
Person p = new Person(ID, Name);
}
A line in the csv file looks like this:
111, james; 222, lynda; 333, luke;
Each line represents a classroom so there would be multiple lines.
Try this:
while (getline(infile, currentline))
{
std::istringstream line{currentline};
if(getline(line, ID, ',') && getline(line, Name, ';'))
Person p = new Person(ID, Name);
}
This while loop would be nested in an !infile.eof while loop.
As a side note, never iterate while( !infile.eof() ) - this is pretty much guaranteed to be a bug. An input stream has multiple failure conditions (eof, failed read etc).
You should simply cast the stream to a boolean value for checking.
The question's a mess, but I think this is what you want:
while (std::getline(infile, currentline))
{
std::istringstream iss(currentline);
if (getline(iss, ID, ',') &&
getline(iss, Name, ';') &&
...)
{
Person p = new Person(ID, Name);
...
}
else
...bad person ;-P...
}
Your while loop seems to already extract a line from the "infile" and stores it in "currentline". Inside the loop you should make a stream out of this string, and use the getlines for "ID" and "Name" on the "currentline"-stream. Otherwise, as it is now, I think you lose every other 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.