I am trying to read in a text file that has a name and age on each line such as this
Tom
55
Bob
12
Tim
66
I then need to pass it to a function which takes in a string and an int such as:
sortDLL.Insert(name, age);
However, I am unsure how to do this. I tested it out with the following and it works (bypassing the text file):
string tom = "tom";
string bob = "bob";
string tim = "tim";
int a = 55;
int b = 12;
int c = 66;
sortDLL.Insert(tom, a);
sortDLL.Insert(bob, b);
sortDLL.Insert(tim, c);
But when I try to read in the text file and send it, the program doesn't run properly. This is what I am currently trying, and I have messed around with a few other things, but have had no luck:
ifstream infile ("names.txt");
while(getline(infile, line));
{
istringstream ss(line);
if (ss >> name)
cin >> name;
else if (ss >> wt)
cin >> wt;
sortDLL.Insert(name, wt);
}
infile.close();
Like always, any help to get this to work would be greatly appreciated, thanks!
I think the correct code should look like this. Remember you have to read 2 line per 1 insert.
while(getline(infile, line))
{
stringstream ss(line);
ss >> wt;
if(ss.fail()) {
name = line;
continue;
}
else {
// cout << name << ":" << wt << endl;
sortDLL.Insert(name, wt);
}
}
Related
I need to split up a line coming in from a file. The file contains a list of books with an id, Author, published date, and title.
91507 Lewis Carroll 1865 Alice in Wonderland
The author name I can just split up into first and last, but what about the title?? I have no idea how to deal with that. Should I just create a second file so I can use getline?
I am a newb and I don't understand how to use stringsteam for this, or split() or anything like that, so if that is what you suggest could you please explain what's happening? I haven't understood any of the examples I've looked at well enough to modify them to suit my purpose.
ifstream fin;
fin.open(filename)
string id;
string first;
string last;
string year;
string title;
if(fin.is_open())
{
while(!fin.eof())
{
fin >> id >> first >> last >> year;
getline(fin, title);
cout << first << " " << last << " " << title << endl;
}
fin.close();
}
Do this:
#include <fstream>
using namespace std;
int main()
{
ifstream fin("somefile.txt");
string id = "";
string authFirst = "";
string authLast = "";
string date = "";
string title = "";
string temp = "";
fin >> id >> authFirst >> authLast >> date >> title;
getline(fin, temp);
title += temp;
cout << title << endl;
return 0;
}
So I understand the basic concept of reading a text file line by line using a while loop, now my question is how do I read each line and then put the contents of those lines into a variable that is part of a structure?
I figured out how to write my text to a file but not how to store the information from that same file so here is what I have so far but it does not seem to work:
This works:
void save(string fileName)
{
Container *traverser = list;
ofstream file;
file.open(fileName);
while (traverser != NULL){
file << traverser->student->getFirstName() << endl;
file << traverser->student->getLastName() << endl;
file << traverser->student->getGrade() << endl;
file << traverser->student->getEdu() << endl;
traverser = traverser->next;
}
}
This doesn't:
void load(string fileName)
{
Container *traverser;
Container* c;
Student *s;
string fname, lname;
int grade;
int edu;
ifstream file;
file.open(fileName);
string line;
while (getline(file, line)){
file >> fname;
file >> lname;
file >> grade;
file >> edu;
s = new Student(fname, lname, grade, edu);
c = new Container();
c->student = s;
}
}
Is it something with my syntax or am I doing it wrong all together?
The program essentially asks for the students first and last names, grade, and education then it stores that into a text file, then it is supposed to load the information from the text file back into the program (I didn't post the whole code because there is a lot).
Thanks!
Additional info: list is a linked list of Structures (students)
I suspect your data is in one line
while (getline(file, line)){
istringstream lstr(line);
lstr >> fname;
lstr >> lname;
lstr >> grade;
lstr >> edu;
s = new Student(fname, lname, grade, edu);
c = new Container();
c->student = s;
}
This could already do the job.
Edit: You might want to #include <sstream>
Okay I read that if we have a string s =" 1 2 3"
we can do :
istringstream iss(s);
int a;
int b;
int c;
iss >> a >> b >> c;
Lets say we have a text file with the following :
test1
100 ms
test2
200 ms
test3
300 ms
ifstream in ("test.txt")
string s;
while (getline(in, s))
{
// I want to store the integers only to a b and c, How ?
}
1) You can rely on succesful convertions to int:
int value;
std::string buffer;
while(std::getline(iss, buffer,' '))
{
if(std::istringstream(buffer) >> value)
{
std::cout << value << std::endl;
}
}
2) or just skip over unnecessary data:
int value;
std::string buffer;
while(iss >> buffer)
{
iss >> value >> buffer;
std::cout << value << std::endl;
}
If you know the pattern of the details in the text file, you could parse through all the details, but only store the int values. For example:
ifstream in ("test.txt")
string s;
while (getline(in, s))
{
getline(in,s); //read the line after 'test'.
string temp;
istringstream strm(s);
s >> temp;
int a = stoi(temp) // assuming you are using C++11. Else, atoi(temp.c_str())
s >> temp;
getline(in,s); // for the line with blank space
}
This above code is still somewhat of a inelegant hack. What you could do besides this is use random file operations in C++. They allow you to move your pointer for reading data from a file. Refer to this link for more information: http://www.learncpp.com/cpp-tutorial/137-random-file-io/
PS: I haven't run this code on my system, but I guess it should work. The second method works for sure as I have used it before.
I have a text file that has information format like this:
id last,first string
for example:
0 Snow,John nothing
1 Norris,Chuck everything
How do i get last name and first name stored separately?
To get information from file, I did:
#include <fstream>
int id;
string str;
string last;
string first;
int main()
{
ifstream myfile(ex.txt);
myfile >> id;
while (myfile)
{
for (int i = 0; i < 4; i++) // this is the amount of times i'll get information from 1 line
{
id = id; // its actually some_structure.id = id, omit
getline(myfile, last, ','); // i think i need to use another function as getline get the whole line
cout << id;
cout << last; // print out the whole line!
}
}
}
ifstream myfile;
string line;
while (getline(myfile, line))
{
istringstream ss(line);
int id;
ss >> id;
string fullname;
ss >> fullname;
string firstname, lastname;
{
istringstream ss2(fullname);
getline(ss2, lastname, ',');
getline(ss2, firstname);
}
}
if (std::ifstream input(filename))
{
int id;
string lastname, firstname, other_string;
while (input >> id && getline(input, lastname, ',') &&
input >> firstname >> other_string)
... do whatever you like...
if (!input.eof())
std::cerr << "error while parsing input\n";
}
else
std::cerr << "error while opening " << filename << '\n';
The code above has more error checking than the other answers I've seen, but admittedly - because it doesn't read text a line at a time then parse out the fields, it would happily accept e.g.:
10 Chuck,
Norris whatever
Would recomend something like this:
string name;
myfile >> id >> name >> str;
first = name.substr(0, name.find(","));
last = name.substr(name.find(",") + 1);
Note that your EOF checking is incorrect.
// The complete code that will do the job
// Please remove uncomment all code
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
ifstream myfile ("ex.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
string last = line.substr(line.find(" ") + 1, line.find(",") - 2);
string first = line.substr(line.find(",") + 1, line.find(",") + line.find(" ") - 1);
}
myfile.close();
}
else {
cout << "Unable to open file";
}
return 0;
}
I'm having an issue reading in a string from a file and then a double from a file afterwards. My professor advised me to put a special getline after each input line, but it hasn't worked and I've deduced that this is the issue with the program. Is there a simpler way to take in doubles?
example of the input file is:
John Smith
019283729102380
300.00
2000.00
Andrew Lopez
293481012100121
400.00
1500.00
the code reads:
while(! infile.eof())
{
getline(infile,accname[count],'\n');
getline(infile, refuse, '\n');
getline(infile,accnum[count],'\n');
getline(infile, refuse, '\n');
infile>>currbal[count];
getline(infile, refuse, '\n');
infile>>credlim[count];
getline(infile, refuse, '\n');
count++;
}
EDIT: Updated in response to OP's clarification.
Based on the sample you provided, this should work:
while(1) {
std::string s1;
if(!std::getline(infile, s1))
break;
std::string s2;
if(!std::getline(infile, s2))
break;
double d1, d2;
if(!(infile >> d1 >> d2))
break;
accname[count] = s1;
accnum[count] = s2;
currball[count] = d1;
credlim[count] = d2;
count++;
}
This code will work for input like:
Adam Sandler
0112233
5 100
Ben Stein
989898
100000000
1
But it won't work for input like:
Adam Sandler
0112233
5 100
Ben Stein
989898
100000000
1
I think Rob Adams's, response has a minor bug when parsing multiple records. After extracting d2 for the first time, the example input stream will contain \nBen Stein\n989898\n100000000\n1, therefore the next call to std::getline() will extract an empty string instead of Ben Stein. So it seems necessary to consume an empty string at the end of each while loop iteration.
I think the following code sample provides a fix:
#include <iostream>
#include <sstream>
int main(int argc, char** argv) {
using std::stringstream;
stringstream infile(stringstream::in | stringstream::out);
infile << "John Smith\n";
infile << "019283729102380\n";
infile << "300.00\n";
infile << "2000\n";
infile << "Andrew Lopez\n";
infile << "293481012100121\n";
infile << "400.00\n";
infile << "1500.00\n";
std::string account_name;
std::string account_number;
double current_balance;
double credit_limit;
int count = 0;
while (std::getline(infile, account_name) &&
std::getline(infile, account_number) >> current_balance >>
credit_limit) {
std::cout << account_name << std::endl;
std::cout << account_number << std::endl;
std::cout << current_balance << std::endl;
std::cout << credit_limit << std::endl;
/*
accname[count] = account_name;
accnum[count] = account_number;
currball[count] = current_balance;
credlim[count] = credit_limit;
*/
count++;
// Consume the leading newline character, which seprates the credit limit
// from the next account name, when infile contains multiple records.
//
// For example, after consuming the record for John Smith, the stream will
// contain: "\nAndrew Lopez\n293481012100121\n400.00\n1500.00\n". If you
// don't consume the leading newline character, calling std::getline() to
// parse the next account name will extract an empty string.
std::string blank;
std::getline(infile, blank);
}
return 0;
}
string str;
while(!infile.eof())
{
getline(infile, accname[count]);// you do not need '\n' it will always read to
// end of the line
getline(infile, accnum[count]);
getline(infile, str);
currbal[count] = atof(str.c_str());
getline(infile, str);
credlim[count] = atof(str.c_str());
count++;
}
\*
for the file
John Smith
019283729102380
300.00
2000.00
Andrew Lopez
293481012100121
400.00
1500.00
*\