Trying to parse a line read from an input file - c++

I have a problem regarding reading input lines from a file. Which is quite a simple task I can manage but the problem is input file lines can consist of words and numbers which then I have to read them seperately and store them in different variables. Let me give an example(italics):
BOOK 100
PENCIL 45
LAPTOP 49
SPOON 34
The reading operation would work regardless of how many spaces there between the Word and the numbers.
I have written this piece of code to read lines directly. But I do not know how to parse them according to the information I gave up.
string fileName;
cout << "Enter the name of the file: ";
cin >> fileName;
ifstream file;
file.open(fileName);
while(file.fail())
{
cout << "enter file name correctly:";
cin >> fileName;
file.open(fileName);
}
string line;
int points;
while(!file.eof())
{
getline(file, line);
stringstream ss(line);
*I do not know what to do here :)*
}

But I do not know how to parse them according to the information I gave up.
Thats quite simple, see below example:
std::stringstream ss("SPOON 34");
std::string s;
int n;
if (ss >> s >> n) {
std::cout << s <<"\n";
std::cout << n <<"\n";
}
outputs:
SPOON
34

You can use sscanf.
char name[100];
int number;
sscanf(line, "%s %d", name, &number);
printf("%s, %d", name, number);
Now I am not sure if this really C++ish. The alternative being using stringstreams like you have started.

Related

How to take multiple lines Input in char arrays without overwriting using getline()

I am a beginner in c++. I am basically trying to take input from user in multiple lines using getline(). But it is overwriting the input every time. Is there any way to get input in char array and not overwrite the previous line or some way to take input in string array and convert it into char array?
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main() {
int lines;
char sentence[1000];
cout << "Enter Number of lines to write: ";
cin >> lines;
for (int i = 0; i <= lines; i++) {
cin.getline(sentence, 1000);
}
ofstream infile("myfile.txt");
infile << sentence;
infile.close();
return 0;
}
You need to do two things:
Open the destination file before you start asking for user input.
In the loop where you ask user input, after every input, dump (append) the buffer content to the destination file.
Something like (pseudocode, not tested)
int main() {
int lines;
char sentence[1000];
cout << "Enter Number of lines to write: ";
cin >> lines;
// prepare the destination file
ofstream infile("myfile.txt");
// now start taking inputs
for (int i = 0; i <= lines; i++) {
cin.getline(sentence, 1000);
infile << sentence; // copy / dump the user input to file
// before you read the next input in same buffer
}
infile.close();
return 0;
}
There are several ways to do this. One of them the previous answer. But after cin >> lines; probably cin.getline(sentence, 1000); can be skipped once. There are two ways to avoid it:
std::cin.ignore(); after cin >> lines;
To get any input from user via string then convert to some information like this:
std::string s{};
std::getline(std::cin, s);
const auto lines = std::stoul(s);
...

Trying to read a .txt file and pull out a specific line based off of a letter entered by user

I have this file with information from the periodic table in a .txt file and Im trying to write a program that allows the user to input the element symbol then read through the file until it finds that symbol and spits out information about that element. At first I got the program to output the cout statement with no information, and now its completely skipping this section after the symbol is entered and going right to the next. Here is my code.
ifstream fin;
ofstream myfile;
string line;
myfile.open("txt file");
fin.open("txt file", ios::app);
while (std::getline(fin, line)) {
fin >> element >> symbol >> atomic_number >> atomic_mass >> physical_state >> density >> melting_point >> boiling_point >> created >> chemical_group >> electronegativity;
if (line == symbol)
{
cout << "information from above"
break;
}
fin.close();
myfile.close();
}
Trying to read a .txt file and pull out a specific line based off of a letter entered by user.
Here is a sample code:
#include <iostream>
#include"string"
#include <fstream>
using namespace std;
int main(void)
{
ifstream fi("1.txt", ofstream::in);
ofstream fo("2.txt", ofstream::out);
string buf;
string s1;
cin >> s1;
while (fi >> buf)
{
if (buf.find(s1) != string::npos) break;
}
fo << buf << endl;
fi.close();
fo.close();
return 0;
}
1.txt is the file you are trying to read. Save the pull out specific line to 2.txt. "s1" is the string entered by the user.
Hope this code is helpful to you.

Reading words and storing them into an array

So I currently have a working programme which successfully finds and displays all the characters in an text file. I now want to be able to read whole words instead of characters and then want to store each word into an array but I have no idea how to even read whole words.
My current code for characters
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream infile("input.txt");
if (!infile)
{
cout << "ERROR: ";
cout << "Can't open input file\n";
}
infile >> noskipws;
while (!infile.eof())
{
char ch;
infile >> ch;
// Useful to check that the read isn't the end of file
// - this stops an extra character being output at the end of the loop
if (!infile.eof())
{
cout << ch << endl;
}
}
system("pause");
}
I now want to be able to read whole words instead of characters and then want to store each word into an array but I have no idea how to even read whole words
std::string word;
infile >> word;
Change the type of ch to std::string so >> will read words.
Use,
std::string word;
infile >> word;
Instead of,
char ch;
infile >> ch;

Sending a String and Int to Function via Text File

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

Reading in from .txt

I have a .txt file with names and grades such as "emiltytaco 56". After the last name, there are 3 blank lines which should not be inserted into my trie and heap. However the code is Aborted and dumped when hitting the blank lines. This is the insert function
while(myfile.good())
{
getline(myfile, line);
name = line.substr(0,line.find("\t"));
stringstream convert((line.substr(line.find("\t")+1)));
convert >> grade;
if(name.at(0) > 96 && name.at(0) < 123)
{
insert(name, grade);
cout << name << " " << grade << endl;
}
}
myfile.close();
should the .close be part of an "else" statement with the if? a friend of mine has this exact thing but his does not abort.
First point, change your loop to something like:
while (getline(myfile, line)) {
// ...
}
Second, it's probably a lot simpler to feed the whole line to the stringstream, and read both pieces from there:
stringstream convert(line);
std::getline(convert, name, '\t');
convert >> grade;
Third, if you want to check for lower-case letters, you're much better off with islower than comparisons to magic numbers like 96 and 123. I wouldn't do the check that way though. If you want to check for a blank line, it would be better to do that directly, with line.empty() immediately after you read it. Using that, you end up with something like:
while (getline(myfile, line))
if (!line.empty()) {
std::istringstream convert(line);
std::getline(convert(line, name);
convert >> grade;
insert(name, grade);
std::cout << name << " " << grade << "\n";
}
There is one more step beyond that though: since the name and grade are (apparently) related, I'd probably define a class for them, and write an extractor to get an object of that type from a stream:
class whatever {
std::string name;
int grade;
friend std::istream &operator>>(std::istream &is, whatever &w) {
std::getline(is, w.name, '\t');
is >> w.grade;
is.ignore(4096, '\n');
return is;
}
};
With that in place, we can read the data from the file quite a bit more simply:
whatever w;
while (myfile >> w) {
insert(w);
std::cout << w.name << " " << w.grade << "\n";
}
Note that in this case, we don't have to check for the blank lines explicitly at all -- we just check whether we could successfully read and convert a whatever from the stream, which will fail for a blank line.