C++ Reading Text File and Storing Data - c++

data.txt contains the following information: firstName, lastName, salary, increment.
James Chong 5000 3
Peter Sun 1000 5
Leon Tan 9500 2
I want to read data.txt, make the necessary calculations, and store the output of 3 variables in anewData.txt:
firstName, lastName, updatedSalary(salary*percentageIncrement)
I only managed to proceed to reading and display information in data.
Below is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
string filename = "data.txt";
ifstream infile;
infile.open(filename);
//if file cannot open, exit program
if (!infile.is_open()){
exit(EXIT_FAILURE);
}
string word;
infile >> word;
while(infile.good()){
cout << word << " ";
infile >> word;
}
system("pause");
return 0;
}
May I know are there any references that I can make use of? Thank you

I am not entirely sure about the question , but you might find substr function useful (if you need to process the data),about writing to a file, you can just create an ofstream output("newData.txt") and simply write the result there. (output << result). Also there is a tokenizer library in BOOST if you don't want to solve it with substr.

You're expecting each line to have 4 words separated by whitespace, so it's as easy as extracting them from infile at each iteration:
while(infile.good()) {
string first_name, last_name;
infile >> first_name;
infile >> last_name;
unsigned int salary, increment;
infile >> salary;
infile >> increment;
}
of course you should check that infile is good after attempting to extract the various pieces, should the lines be malformed.
You can get fancier here, but this covers your basic needs.

Related

How would I split a string by number of characters using getline?

Is there a way to take in a specified number of characters using cin or getline from a txt file and stop reading once the character limit is reached? I would like to read exactly 15 characters from a text file without stopping at any blank spaces or other delimiting characters.
ifstream inFile;
inFile.open("file.txt");
string sname;
//this is what I put at the moment but I don't believe it serves the purpose of what I'm looking for
cin >> setw(15) >> sname;
I went through previously posted questions but I couldn't find a clear answer.
I don't think you can do that with getline() or cin,
but this should works:
#include <fstream>
#include <string>
int main()
{
std::ifstream inFile;
inFile.open("file.txt");
std::string sname;
sname.resize(15);
inFile.read(&sname[0], 15 * sizeof(char));
}

C++ ignore alphabetical characters when reading input from a file

I have a program that takes an input stream from a text file, which contains positive integers, delimited by spaces. The file contains only numbers and one instance of abc which my program should ignore before continuing to read data from the file.
this is my code and it does not work
int line;
in >> line;
in.ignore(1, 'abc');
in.clear();
could someone specify what the problem is? essentially, I want to discard the alpha input, clear cin and continue to read from file but I get an infinite loop.
This code should work
I get three parts from the input stream, and put the useful parts into a stringstream and read from it
int part1, part2;
std::string abc;
in >> part1 >> abc >> part2;
std::stringstream ss;
ss << part1 << part2;
int line;
ss >> line
You can explicitely ignore any alphabetical character this way:
#include <locale>
#include <iostream>
std::istream& read_number(std::istream& is, int& number) {
auto& ctype = std::use_facet<std::ctype<char>>(is.getloc());
while(ctype.is(std::ctype_base::alpha, is.peek())) is.ignore(1);
return is >> number;
}
int main() {
using std::string;
using std::cin;
using std::locale;
int number;
while(read_number(std::cin, number)) {
std::cout << number << ' ';
}
}
For input like "452abc def 23 11 -233b" this will produce "452 23 11 -233".

input data from a file when each is a different type and a comma delimiter

I need to read from file a series of information that is separated by commas
example
Orionis, 33000, 30000, 18, 5.9
Spica, 22000, 8300, 10.5, 5.1
i'm having a hard time figuring out the getline structure to make this work. The CS tutor, in the lab, says to use a getline for this but i can't seem to make it work (visual studio doesn't recognize getline in this function)
#include <iostream>
#include <fstream>
#include "star.h"
#include <string>
using namespace std;
char getChoice();
void processSelection(char choice);
void processA();
(skipping crap you don't need)
static char filePath[ENTRY_SZ];
void processA() {
ifstream openFile;
long temp, test;
double lum, mass, rad;
char name;
cout << "Please enter the full file path" << endl;
cin >> filePath;
openFile.open(filePath, ios::in);
if (openFile.good() != true) {
cout << "this file path was invalid";
}
while (openFile.good())
{
star *n = new star;
// getline(openFile, name, ',');
star(name);
getline(openFile, temp, ',');
n->setTemperature(temp);
getline(openFile, lum, ',');
n->setLuminosity(lum);
getline(openFile, mass, ',');
n->setMass(mass);
cin >> rad;
n->setRadius(rad);
}
}
From what i'm reading online (including older posts) and what my CS tutor says this should work so any help will be appreciated.
The suggestion to use std::getline() is likely implying that you'd first read a std::string and then deal with the content of this std::string, e.g., using std::istringstream.
I'd suggest not to use std::getline() and, of course, to also check inputs after they are read. To deal with the comma separator after non-std::string fields I'd use a custom manipulator:
std::istream& comma(std::istream& in) {
if ((in >> std::ws).peek() == ',') {
in.ignore();
}
else {
in.setstate(std::ios_base::failbit);
}
return in;
}
This manipulator skips leading whitespace (using the manipulator std::ws) and then simply checks if the next character is a comma. If so, the comma is extracted, otherwise the stream is set into failure mode and further attempts to read will fail until the failure state is dealt with (e.g., by using in.clear() and probably getting rid of any offending characters).
With this manipulator it is easy to read the respective values. Note, that when switching from formatted to unformatted input it is likely necessary that leading whitespace (e.g., in this case line breaks) need to be ignored. Also, the code below first attempts to read the values and uses them only when this attempt was successful: input shall always be checked after a read attempt was made, not before!
// ...
long temp;
double lum, mass, rad;
std::string name;
while (std::getline(in >> std::ws, name, ',')
>> temp >> comma
>> lum >> comma
>> mass >> comma
>> rad) {
// use the thus read values
}

Splitting string into smaller strings from text input

Reading in a text file to a C++ program I'm working on, and storing each string in a node for a double-linked list. Problem is, I don't know how to split up a line into smaller strings, separating them where the space is.
For instance, one input is
"Duck Donald 940-666-5678"
and I'm attempting to split it into a lastname string, a firstname string, and a phnum string at the white space. The result would essentially be:
lastname==Duck
firstname==Donald
phnum==940-666-5678
How would I do this?
Although I not sure how you're extracting this data, I believe you should just be able to use the >> operator.
Example:
string lastname;
string firstname;
string phnum;
ifstream myFile;
myFile.open("example.txt");
myFile >> lastname >> firstname >> phnum;
I am not quite sure how you are reading in from your file, but this bit of code may help you.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
istringstream iss(s);
do
{
string sub;
iss >> sub;
cout << "Substring: " << sub << endl;
} while (iss);
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
Make sure to search Stackoverflow/Google before asking because you can find your answer really easily many times (see my resources)
Resources: http://www.cplusplus.com/doc/tutorial/files/, Split a string in C++?

Reading in a .txt file word by word to a struct in C++

I am having some trouble with my lab assignment for my CMPT class...
I am trying to read a text file that has two words and a string of numbers per line, and the file can be as long as anyone makes it.
An example is
Xiao Wang 135798642
Lucie Chan 122344566
Rich Morlan 123456789
Amir Khan 975312468
Pierre Guertin 533665789
Marie Tye 987654321
I have to make each line a separate "student", so I was thinking of using struct to do so, but I don't know how to do that as I need the first, last, and ID number to be separate.
struct Student{
string firstName;
string secondName;
string idNumber;
};
All of the tries done to read in each word separately have failed (ended up reading the whole line instead) and I am getting mildly frustrated.
With the help from #Sylence I have managed to read in each line separately. I am still confused with how to split the lines by the whitespace though. Is there a split function in ifstream?
Sylence, is 'parts' going to be an array? I saw you had indexes in []'s.
What exactly does the students.add( stud ) do?
My code so far is:
int getFileInfo()
{
Student stdnt;
ifstream stdntFile;
string fileName;
char buffer[256];
cout<<"Please enter the filename of the file";
cin>>filename;
stdntFile.open(fileName.c_str());
while(!stdFile.eof())
{
stdFile.getLine(buffer,100);
}
return 0;
}
This is my modified and final version of getFileInfo(), thank you Shahbaz, for the easy and quick way to read in the data.
void getFileInfo()
{
int failed=0;
ifstream fin;
string fileName;
vector<Student> students; // A place to store the list of students
Student s; // A place to store data of one student
cout<<"Please enter the filename of the student grades (ex. filename_1.txt)."<<endl;
do{
if(failed>=1)
cout<<"Please enter a correct filename."<<endl;
cin>>fileName;
fin.open(fileName.c_str());// Open the file
failed++;
}while(!fin.good());
while (fin >> s.firstName >> s.lastName >> s.stdNumber)
students.push_back(s);
fin.close();
cout<<students.max_size()<<endl<< students.size()<<endl<<students.capacity()<<endl;
return;
}
What I am confused about now is how to access the data that was inputted! I know it was put into a vector, but How to I go about accessing the individual spaces in the vector, and how exactly is the inputted data stored in the vector? If I try to cout a spot of the vector, I get an error because Visual Studio doesn't know what to output I guess..
The other answers are good, but they look a bit complicated. You can do it simply by:
vector<Student> students; // A place to store the list of students
Student s; // A place to store data of one student
ifstream fin("filename"); // Open the file
while (fin >> s.firstName >> s.secondName >> s.idNumber)
students.push_back(s);
Note that if istream fails, such as when the file finishes, the istream object (fin) will evaluate to false. Therefore while (fin >> ....) will stop when the file finishes.
P.S. Don't forget to check if the file is opened or not.
Define a stream reader for student:
std::istream& operator>>(std::istream& stream, Student& data)
{
std::string line;
std::getline(stream, line);
std::stringstream linestream(line);
linestream >> data.firstName >> data.secondName >> data.idNumber;
return stream;
}
Now you should be able to stream objects from any stream, including a file:
int main()
{
std::ifstream file("data");
Student student1;
file >> student1; // Read 1 student;
// Or Copy a file of students into a vector
std::vector<Student> studentVector;
std::copy(std::istream_iterator<Student>(file),
std::istream_iterator<Student>(),
std::back_inserter(studentVector)
);
}
Simply read a whole line and then split the string at the spaces and assign the values to an object of the struct.
pseudo code:
while( !eof )
line = readline()
parts = line.split( ' ' )
Student stud = new Student()
stud.firstName = parts[0]
stud.secondName = parts[1]
stud.idNumber = parts[2]
students.add( stud )
end while