So i'm writing down these objects in file, reading them, and later updating stock count. I have written two objects in file and they're being read perfectly but not updating the stock after the decrement function is called. I don't want to change the data type of ID from string to character array as that won't be feasible for my project. Can it work with string?
Please help.Where's my code going wrong
#include<fstream>
#include <string>
#include <iostream>
#include<cstring>
using namespace std;
class Item
{
string ID;
char name[10];
int stock;
public:
Item()
{
}
Item(string id, char n[10], int s)
{
ID=id;
strcpy(name,n);
stock=s;
}
void writeuser(){
fstream fp;
fp.open("harmain.dat",ios::out|ios::app);
fp.write((char*)this,sizeof(Item));
fp.close();
}
void readuser(string id){
fstream fp;
fp.open("harmain.dat",ios::in|ios::out);
fp.read((char*)this,sizeof(Item));
while(1){
if(this->ID!=id){
cout<<"name:"<<name;
cout<<"stock"<<stock;
break;
}
fp.read((char*)this,sizeof(Item));
}
fp.close();
}
void decrement(string id){
fstream fp;
Item test;
fp.open("harmain.dat",ios::in|ios::out);
fstream fp2;
fp2.open("temp.dat",ios::out|ios::in);
while( fp.read((char*)&test,sizeof(Item))){
if(test.ID==id){
test.stock=test.stock-1;
fp2.write((char*)&test,sizeof(Item));
}else{
fp2.write((char*)&test,sizeof(Item));
}
}
remove("harmain.dat");
rename("temp.dat","harmain.dat");
fp.close();
fp2.close();
}
};
int main
{ Item i1;
i1.readuser("APP01");
cout<<endl;
i1.decrement("APP01");
i1.readuser("APP01");
// Item i1("APP01", "Apple",100);
// i1.writeuser();
// i1.readuser("APP01");
// Item i2("BAN01","Bananas",200);
// i2.writeuser();
}
Related
I made a conceptual program to add to my larger program, but I'm having an issue with a counter.
I have found plenty of excellent recourses on how to count lines in a data file (using various methods) I've tried all of them.
What is happening is, that I set up 3 arrays to hold various data. Wrote that data to a file.. and now. Before I read the data back I want to be able to know the size ( or how many lines are in the file).
I can print out all of the data from the file but the counter keeps only being set as 1.
In my larger program the number or lines will not be known to begin with.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <ctime>
#include <string>
using namespace std;
class ReadWrite
{
public:
ofstream OutputFile,temp;
ifstream InputFile;
string taskID[3]={"1","2","3"};
string task[3]={"blah1","blah2","blah3"};
string date[3]={"11/11/1111", "12/12/1212","13/13/1313"};
string line[3];
string lines;
int count=0;
void write2file();
void readfile();
void remove();
};
void ReadWrite::readfile()
{
InputFile.open("TODOs.txt");
if (!InputFile.is_open())
{
cout<<"No saved TODOs.\n";
}
else
{
cout<<"TODOs uploading.\n";
while(InputFile>>lines);
{
cout<<lines<<endl;
count++;
}
InputFile.close();
InputFile.open("TODOs.txt");
cout<<"lines: "<<count<<endl;
for (int i=0;i<3;i++)
{
while(getline(InputFile,line[i]))
{
cout<<line[i]<<endl;
}
}
InputFile.close();
}
}
void ReadWrite::write2file()
{
OutputFile.open("TODOs.txt");
for(int i=0; i<3;i++)
{
OutputFile<<taskID[i]<<"\t"<<date[i]<<"\t"<<task[i]<<'\n';
}
OutputFile.close();
}
int main()
{
ReadWrite rw;
bool progLoop = true;
do
{
// SimpAlphaMenu sam(choices, len);
// int choice = sam.showMenu();
char choice;
cin>>choice;
if (choice=='+')
{
rw.write2file();
progLoop=true;
}
else if (choice=='-')
{cout<<"You are in -\n";}
else if (choice=='?')
{
rw.readfile();
progLoop=true;
}
else
progLoop = false;
}while(progLoop);
}
After editing in suggestions from #Retired Ninja the code seems to be working fine.
void ReadWrite::readfile() {
InputFile.open("TODOs.txt");
if (!InputFile.is_open())
{
cout<<"No saved TODOs.\n";
}
else
{
cout<<"TODOs uploading.\n";
while(getline(InputFile,lines)) //Edited this line here
{
// cout<<lines<<endl;
count++;
}
InputFile.close();
InputFile.open("TODOs.txt");
cout<<"lines: "<<count<<endl;
for (int i=0;i<3;i++)
{
while(getline(InputFile,line[i]))
{
cout<<line[i]<<endl;
}
}
InputFile.close();
} }
I want to do a program where I key in the a question and answer to a text file with unique id(auto increment number). Currently the program only works if the text file is empty, once I have written something in the text file, the next time I run it, it does not show any output. Just blank CMD
#include<fstream>
#include<stdlib.h>
#include<string.h>
using namespace std;
class stud
{
public:
string answers, questions;
float score, totalScore;
int rollno;
stud()
{
rollno=0;
}
int get_no();
void getdata();
};
int stud::get_no()
{
ifstream outfile("questions.txt",ios::in);
int quizID;
while(!outfile.eof())
{
outfile>>rollno;
outfile>>questions;
outfile>>answers;
if(outfile.eof())
{
break;
}
}
quizID = rollno;
quizID = quizID + 1;
outfile.close();
return quizID;
}
void stud::getdata()
{
ofstream outfile("questions.txt", ios::out|ios::app);
rollno = get_no();
cout<<"Add New Question\n";
getline(cin,questions);
cout<<"Add New Answers\n";
getline(cin,answers);
outfile<<"ID "<<rollno<<": Question : "<<questions<<" Answer : "<<answers<<"\n";
outfile.close();
}
int main()
{
stud s1;
s1.getdata();
return 0;
}
I have a list of video game characters that are organized in a certain way.
I want to be able to take their names only from the list and sort it alphabetically.
The list is formatted by:
Last Name, First Name, Game, Relase Date, Score, Developer
The list is:
Snake, Solid, Metal Gear Solid, 9/3/1998, 94, Konami
Drake, Nathan, Uncharted, 11/19/2007, 90, Naughty Dog
Guy, Doom, Doom, 5/13/1993, 95, iD
The output I want is:
Drake, Nathan
Guy, Doom
Snake, Solid
I can print out there names only in the order in which they are in the text file. How do I compare the last names, then print out the full names?
Here is my code so far:
#include <fstream>
#include <iostream>
#include <string>
#include <time.h>
#include <cstdlib>
#include <sstream>
using namespace std;
ifstream inFile;
class Characher{
private:
string first;
string last;
public:
Character(){};
void getLast(){
if(inFile.is_open()){
getline(inFile, last,',');
} else {
cout<<"Hmm.."<<endl;
}
}
void getFirst(){
if(inFile.is_open()){
getline(inFile, first,',');
} else {
cout<<"No First Name here..."<<endl;
}
}
void printLast(){
cout<<last<<",";
}
void printFirst(){
cout<<first<<endl;
}
};
class Dev{
private:
string Developer;
public:
Dev(){};//null constructor
void printDeveloper(){
cout<<"Developer: "<<Developer<<endl;
}
void getDeveloper(){
if(inFile.is_open()){
getline(inFile, Developer);
} else {
cout<<"Nothing here..."<<endl;
}
}
};
class Game{
private:
string game;
public:
Game(){};
void getGameName(){
if(inFile.is_open()){
getline(inFile, game,',');
} else{
cout<<"What game was they frum?"<<endl;
}
}
void printGame(){
cout<<"Game: "<<game;
}
};
class RelDate_And_Score{
private:
string ReleaseDate;
string Score;
public:
RelDate_And_Score(){};
void GetRelDate(){
if(inFile.is_open()){
getline(inFile, ReleaseDate, ',');
} else{
cout<<"Could not find Release Date"<<endl;}
}
void getScore(){
if(inFile.is_open()){
getline(inFile, Score, ',');
} else{
cout<<"Could not find Score"<<endl;}
}
void PrintDate(){
cout<<"Release Date: "<<ReleaseDate<<" | ";}
void PrintScore(){
cout<<"Score: "<<Score<<endl;}
};
int main(){
inFile.open("Games.dat");
Dev d;
Characher c;
RelDate_And_Score r;
Game g;
for (int i=0; i<3; i++)
{
c.getLast();
c.getFirst();
g.getGameName();
r.GetRelDate();
r.getScore();
d.getDeveloper();
c.printLast();
c.printFirst();
}
return 0;
}
I see you work directly with the file for each method (getLast() etc). This is not the best way to do it, as accessing the file is costly and less efficient.
You should construct a representation of the file in memory: Start with representing each row as a Character class such as:
class Character
{
public:
Character(const string & firstname, const string & secondname, const string & game, const string & releasedate, const string & score, const string & developer)
:
m_firstname(firstname), m_secondname(secondname), m_game(game), m_releasedate(releasedate), m_score(score), m_developer(developer)
{}
private:
string m_firstname, m_secondname, m_game, m_releasedate, m_score, m_developer;
};
Open the file, read each row, construct a Character using the parsed strings (split by commas).
As tadman proposed in a comment, you can use the std::sort method to order the Character by names. Implement the operator< in the Character class such as:
class Character
{
//...
bool operator<(const Character & c)
{
return m_firstname < c.m_firstname;
}
//...
};
So you can use the std::sort on your vector<Character> m_characters
std::sort(m_characters.begin(), m_characters.end());
I am trying to read a string line for line down a .txt file in order to initiate an array of objects using a constructor that takes a string.
The text file is written like
TransAm
Mustang
Corvette
I feel like my loop is not iterating the information I want to be set correctly. Is there an easy way of accomplishing this?
main.cc
#include <string>
#include <iostream>
#include "Car.cc"
#include <fstream>
using namespace std;
int main()
{
Car cars[3];
string STRING;
ifstream infile;
infile.open("cars.txt");
// THIS IS HOW IT'S ACHIEVED USING FOR-LOOP - Sam
for(int i = 0; i<3 && infile;++i){
getline(infile,STRING);
cars[i].setName(STRING);
}
/* THIS IS WHAT I HAD
while(!infile)
{
getline(infile,STRING);
for(int i = 0; i<sizeof(cars);i++){
cars[i].setName(STRING);
}
}
*/
infile.close();
for(int j = 0;j<sizeof(cars);j++){
cars[j].print();
}
}
Car.h
#include <string>
using namespace std;
class Car{
public:
Car();
Car(string);
string getName();
void setName(string);
void print();
private:
string name;
};
Car.cc
#include <string>
#include "Car.h"
using namespace std;
Car::Car()
{
}
Car::Car(string s)
{
setName(s);
}
void Car::setName(string s)
{
name = s;
}
string Car::getName()
{
return name;
}
void Car::print()
{
cout << name;
}
These points need to be corrected:
while (!infile) prevents you from entering the loop.
You don't need two loops.
You can modify your loop like this:
for (int i = 0; i < sizeof(cars) && getline(infile, STRING); ++i)
cars[i].setName(STRING);
Or like this:
for (int i = 0; i < sizeof(cars) && infile; ++i) {
getline(infile, STRING);
cars[i].setName(STRING);
}
Your loop does at the moment nothing if the file is correctly opened. It will only enter if the call to open was unsuccessful.
Change your loop to either
while (getline(infile,STRING))
{
//...
}
or
while (infile)
{
//...
}
As it's been said, "Change while(!infile) to while(getline(infile,STRING))" but do not forget to remove the getline(infile,STRING); afterwards.
Here I have a program that reads in some employee data from a file and stores them in an array of structs. What I am trying to do with the "sort_by_age" function is to sort this data based on date of birth to where the data is listed from oldest employee to youngest employee.The "read_file" function works fine, and the program compiles fine, but the output is incorrect, the program doesnt sort the data properly as i would like. Any help would be greatly appreciated.
Heres a few lines from the file to give an idea of the format
114680858 19670607 Matilda Vincent MI
114930037 19471024 Desdemona Hanover ID
115550206 19790110 Xanadu Perlman ND
116520629 19630921 Alexander Hall SD
so for example if this was all the lines in the file(its not), i want it to sort Desdemona's info first, then alexander's, then, matilda's, then xanadu's.
#include<string>
#include<iostream>
#include<fstream>
using namespace std;
struct employees // employee data
{
int ss_number;//social security
int dob;//date of birth YYYY/MM/DD Ex.) 19870314=1987/03/14
string f_name;
string l_name;
string state; //state of residence };
void read_file()//read file into array of 1000 structs
{
ifstream data("/home/www/class/een118/labs/database1.txt");
employees array[100]
if(!data.fail())
{
int i;
for(int i=0;i<100;i++)
{
data>>array[i].ss_number
>>array[i].dob
>>array[i].f_name
>>array[i].l_name
>>array[i].state;
}
for(int i=0;i<100;i++)
{
cout<<array[i].ss_number>>" "<<array[i].dob>>" "<<array[i].f_name>>" "<<
array[i].l_name>>" "<<array[i].state;
}}}
void print_person(employees e)
{
cout<<e.ss_number>>" "<<e.dob>>" "<<e.f_name>>" "<<e.l_name>>" "<<e.state;
}
void sort_by_age(employees array[])
{
employees temp;
for(int i=0;i<100;i++)
{
for(int j=i+1;j<100;j++)
{
if(array[j].dob<array[i].dob)
{
temp=array[i];
array[i]=array[j];
array[j]=temp;}
print_person(array[j]);
cout<<"\n";}}}
int main()
{
employees array[100];
read_file(array);
sort_by_age(array);
}
Use std::sort, preferably with a lambda, for example.
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
struct employee {
int social_security_id;
int date_of_birth;
string first_name;
string last_name;
string state;
};
// parses and returns a vector of employees from the given stream.
std::vector<employee> parse_employees(ifstream ifs)
{
std::string str;
std::vector<employee> v;
while (!ifs.eof()) {
employee e;
ifs >> e.social_security_id >> e.date_of_birth >> e.first_name >> e.last_name >> e.state;
v.push_back(e);
}
return v;
}
int main(int argc, char* argv[])
{
ifstream ifs("/home/www/class/een118/labs/database1.txt");
auto employees = parse_employees(ifs);
std::sort( std::begin(employees), std::end(employees),
[]( const employees &a, const employees &b )
{
return ( a.date_of_birth > b.date_of_birth );
});
for (auto e : v) {
cout << e.social_security_id << e.date_of_birth << e.first_name << e.last_name << endl;
}
}