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;
}
Related
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();
}
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
...
}
I currently have a text file that is as follows:
12 6 4 9
It is a very simple text file since I want to just get one line working and then maybe expand to multiple lines later. Extra aside: this is for a RPN calculator I am working on.
I want to go through this text file character by character. The way I currently have it implemented is with a simple while loop:
string line;
while (!infile.eof()){
getline(infile, line);
if (isdigit(line[0])){
rpn_stack.push_back(atof(line.c_str()));
}
}
rpn_stack is a vector since I will not be using the built in stack libraries in C++.
The problem I am currently having is that the output is just outputting "12". Why is this?
Is there a way that I can traverse through the file character by character instead of reading as a line? Is it breaking because it finds a white space (would that be considered the EOF)?
EDIT:
The code has been rewritten to be as the following:
string line;
while (!infile.eof()){
getline(infile, line);
for (int i = 0; i < line.size(); i++){
if (isdigit(line[i])){
rpn_stack.push_back(atof(line.c_str()));
}
}
}
The output is 12 5 different times, which is obviously wrong. Not only are there 4 items in the txt document, but only one of them is a 12. Can someone give some insight?
This will read as many doubles from infile as possible (i.e. until the end of file or until it comes across a token that isn't a double), separated by whitespace.
for (double d; infile >> d;)
rpn_stack.push_back(d);
If you need parse line-by-line, as #ooga says you will need a two-stage reader that looks something like this:
for (std::string line; getline(infile, line);) {
std::istringstream stream{line};
for (double d; stream >> d;)
rpn_stack.push_back(d);
}
Bonus hint: don't use .eof()
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
}
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.