I'm doing an assignment which requires file handling in C++.Assignment is long enough to be posted here, but i have made a similar simple code to elaborate my question.The following code is not read all data from file it only read the last record
please help me to make it correct.
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string.h>
//class
class medicine{
int id;
char med_name[50];
int price;
int quantity;
char date[50];
public:
void data_entery(){
//int i;char na[50];int p;int q;char da[50];
cout<<"Enter id: ";
cin>>id;
cout<<"Enter name: ";
cin>>med_name;
cout<<"Enter price: ";
cin>>price;
cout<<"Enter quantity: ";
cin>>quantity;
cout<<"Enter exp_date: ";
cin>>date;
}
void display(){
cout<<this->id<<"\t "<<this->med_name<<"\t "<<this->price<<"\t"<<this- >quantity<<"\t "<<this->date;
}
}med[10];
using namespace std;
int main (){
//writing in file
ofstream wfile("medicines.txt",ios::app|ios::binary);
wfile.seekp(0,ios::end);
int rec=wfile.tellp()/sizeof(medicine);
cout<<"there are "<<rec<<" records";
med[rec].data_entery();
wfile.write(reinterpret_cast<char *>(&med),sizeof(medicine));
wfile.close();
//reading in file
ifstream rfile("medicines.txt",ios::in|ios::binary);
rfile.seekg(0,ios::end);
rec=rfile.tellg()/sizeof(medicine);
rfile.seekg(0,ios::beg);
cout<<"there are "<<rec<<" records";
for (int k=0;k<rec;k++){
med[k].display();
}
rfile.read(reinterpret_cast<char *>(&med),sizeof(med)*rec);
rfile.close();
getch();
return 0;
}
I am assuming that your file medicines.txt is initially empty.
What you have done wrong is that you have made 10 objects of the medicine class, but you are writing only one object to the file.
What you need to do here is:
for (int i=0; i < 10; i++) {
med[i].data_entery();
wfile.write(reinterpret_cast<char *>(&med),sizeof(medicine));
}
wfile.close();
Now you'll need to add 10 medicines, after details of each medicine has been added, that medicine will be written to the file.
I hope this helps.
Here is a better version of your code
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string.h>
using namespace std;
//class
class medicine
{
int id;
char med_name[50];
int price;
int quantity;
char date[50];
public:
void data_entery()
{
//int i;char na[50];int p;int q;char da[50];
cout<<"\nEnter id: ";
cin>>id;
cout<<"Enter name: ";
cin>>med_name;
cout<<"Enter price: ";
cin>>price;
cout<<"Enter quantity: ";
cin>>quantity;
cout<<"Enter exp_date: ";
cin>>date;
}
void display()
{
cout<<"\nID :"<<this->id<<"\nName :"<<this->med_name<<"\nPrice :"<<this->price<<"\nQuantity :"<<this->quantity<<"\nExp Date :"<<this->date<<"\n";
}
}med;
int main ()
{
//writing in file
ofstream wfile("medicines.txt",ios::app|ios::binary);
wfile.seekp(0,ios::end);
int rec=wfile.tellp()/sizeof(medicine);
cout<<"\nthere are "<<rec<<" records";
med.data_entery();
wfile.write(reinterpret_cast<char *>(&med),sizeof(medicine));
wfile.close();
//reading in file
ifstream rfile("medicines.txt",ios::in|ios::binary);
rfile.seekg(0,ios::end);
rec=rfile.tellg()/sizeof(medicine);
rfile.seekg(0,ios::beg);
cout<<"\nthere are "<<rec<<" records";
while(rfile.read(reinterpret_cast<char *>(&med),sizeof(med)))
{
med.display();
}
rfile.close();
getch();
return 0;
}
Now, when you are using files, you do not need to create an array of objects. Once you store the object into the file, you can just reuse that object. The data can be accessed from the File. That is what I have done in this code. I have edited this code in such a manner as to not change your method, instead just corrected the problems and also made your code a little better. In each run of this code, you enter the details of one record, and then the details of all the records are shown.
The good thing about this code is, you can enter as many records as you want. You are not restricted to 10 records like your original code.
Related
hi guys so we have a school activity, and we are instructed to make an inventory system. I managed to do the input part of the code however i cannot display the same way the picture below shows:
This is the code of my work:
#include <iostream>
#include <iomanip>
#include <cstring>
#include <windows.h>
#include <cstdlib>
#include <fstream>
using namespace std;
//global declaration
int i;
int j;
const int passctr=3;
struct inventory{
double price;
int stock;
int sold;
int left;
};
struct itemType {
inventory items;
string itemname;
string brand;
};
struct userType{
string name;
string password;
};
int main()
{
//declaration
int prodqty,brandqty;
int prodarr;
int qty;
itemType item[prodqty],display;
userType user;
for(i=0;i<passctr;i++)
{
cout<<"Try no."<<i+1<<endl;
string xpassword="pogisibry";
cout<<"PRODUCT INVENTORY SYSTEM"<<endl;
cout<<"Enter Username: ";
getline(cin,user.name);
cout<<"Enter Password: ";
getline(cin,user.password);
try
{
if(user.password!=xpassword)
{
throw user.password;
}
else
{
cout<<"Welcome user "<<user.name<<"!!!"<<endl;
break;
}
}
catch (string reenter)
{
cout<<"Wrong password!"<<endl
<<"Please re enter!"<<endl;
}
system("pause");
system("cls");
}
if (i==passctr)
{
cout<<"locking inventory system!"<<endl
<<"exiting the program...";
exit(1);
}
cout<<"Enter desired number of products: ";
cin>>prodqty;
for(i=0;i<prodqty;i++)
{
cin.ignore();
cout<<"Product ["<<i+1<<"]: ";
getline(cin,item[i].itemname);
cout<<"How many "<<item[i].itemname<<"? : ";
cin>>brandqty;
cout<<endl;
for(j=0;j<brandqty;j++)
{
cin.ignore();
cout<<item[i].itemname<<"["<<j+1<<"]: ";
getline(cin,item[j].brand);
cout<<endl;
cout<<"Price: Php ";
cin>>item[j].items.price;
cout<<"Stock: ";
cin>>item[j].items.stock;
cout<<"Sold: ";
cin>>item[j].items.sold;
}
}
cout<<"PROD NO. PRODUCT NAME PRICE STOCK SOLD LEFT"<<endl;
for(i=0;i<prodqty;i++)
{
cout<<left<<setw(13)<<"["<<i+1<<"]"
<<setw(12)<<item[i].itemname
<<setw(14)<<item[i].brand
<<endl;
for(j=0;j<brandqty;j++)
{
item[j].items.left=item[j].items.stock-item[j].items.sold;
cout<<left<<setw(10)<<item[j].items.price
<<setw(10)<<item[j].items.stock
<<setw(10)<<item[j].items.sold
<<setw(10)<<item[j].items.left
<<endl;
}
}
}
I want to fix the display just like on the image above.
I did some array but it did not display other items I input.
#include <iostream>
#include<fstream>
using namespace std;
int main()
{
int a;
cout<<"enter key ";
cin>>a;
if(a==1)
{
string info[0][1];
cout<<"enter your name ";
getline(cin, info[0][0]);
cout<<"enter father's ";
getline(cin, info[0][1]);
ofstream file("info.txt");
for(int i=0;i<=1;i++)
{
file<<info[0][i]<<" ";
}
file.close();
}
int b;
cout<<"enter b ";
cin>>b;
if(b==2)
{
char info[0][1];
ifstream file("info.txt");
for(int j=0;j<=1;j++)
{
file>>info[0][j];
}
cout<<endl;
for(int i=0;i<=4;i++)
{
cout<<info[0][i]<<" ";
}
}
return 0;
}
I want to store user and his father's name (other info as well which is not mentioned in code) in the form of 2d array, and ofstream that array and later ifstream the same.
in the code:
After taking input a=1, it displays "enter your name", to which it is not taking any input i.e nothing gets typed in the output window from keyboard. (no compiler error) Please help!!
I am coding in code blocks.
This is not legal C++ (because arrays of size zero are not legal).
string info[0][1];
cout<<"enter your name ";
getline(cin, info[0][0]);
cout<<"enter father's ";
getline(cin, info[0][1]);
ofstream file("info.txt");
for(int i=0;i<=1;i++)
{
file<<info[0][i]<<" ";
}
All you need is two strings, so just
string info[2];
cout<<"enter your name ";
getline(cin, info[0]);
cout<<"enter father's ";
getline(cin, info[1]);
ofstream file("info.txt");
for(int i=0;i<2;i++)
{
file<<info[i]<<" ";
}
Thne when you try to read them back, you've made the same error, and added a new one
char info[0][1];
Why did you switch to char here? Again you need two strings.
string info[2];
Finally for some reason at the end you are trying to output five strings.
for(int i=0;i<=4;i++)
{
cout<<info[0][i]<<" ";
}
Again two is the magic number
for(int i=0;i<2;i++)
{
cout<<info[i]<<" ";
}
Plus you have the problem mentioned by Yksisarvinen. You need to fix that in the way mentioned in the link.
The code below,works fine but it does not take any value for age and terminates.`
#include <iostream>
#include <string>
using namespace std;
class user{
int id,level=1,kills=0,age;
char name[20],server[40];
public:
void get(){
cout<<"Enter your name:";
cin>>name[20];
cout<<"Enter your age:";
cin>>age;
}
};
int main(){
user u;
u.get();
return 0;
}
/*Output
Enter your name:Jack
Enter your age:
C:\Users\user\documents\c++
*/
In the output section ,age is not accepted and the program terminates.
Use string name instead of char name[20] to take multi-character value. char name[20] will terminate after taking a single character.
Also, its valued will not be displayed on giving output.
Modified code for reference.
#include <iostream>
#include <string>
using namespace std;
class user{
int id,level=1,kills=0,age;
string name,server;
public:
void get(){
cout<<"Enter your name:";
cin>>name;
cout<<"Enter your age:";
cin>>age;
}
//test output
void put(){
cout<<name<<endl;
cout<<age<<endl;
}
};
int main(){
user u;
u.get();
//test
u.put();
return 0;
}
Just modify the code to this :
#include <iostream>
#include <string>
using namespace std;
class user{
int id,level=1,kills=0,age;
char name[20],server[40];
public:
void get(){
cout<<"Enter your name:";
cin>>name; // changes done here
cout<<"Enter your age:";
cin>>age;
}
};
int main(){
user u;
u.get();
return 0;
}
Job Done :)
Your problem is here:
cin>>name[20];
Why:
'name[20]' is 21th char of the array you defined before. It counts from 0! As this, it is simply a single char. If you now enter more than a single char, the rest is read by the cin>>age.
Example:
cout<<"Enter your name:";
cin>>name[20];
cout<<"Enter your age:";
cin>>age;
std::cout << "Name " << name << std::endl;
std::cout << "Age " << age << std::endl;
And entering:
Enter your name:1234
Enter your age:Name
Age 234
As you see, the '1' is now in the name and the rest is stored in age.
But attention: You defined your array as `name[20], which means you have 0..19 elements. Accessing name[20] is wrong!
But what you simply want to do was:
cin >> name;
The easiest way to handle strings (a long sequence of characters) or even the strings that have spaces just use the following library in C++.
#include <bits/stdc++.h>
Then just declare a string variable.
String name;
Now you can save a very long string without any error. e.g.
name = jshkad skshdur kslsjue djsdf2341;
and you'll get no error, enjoy ;)
I have the following simple program, but the last line of code getline(cin, topicClass) is never excuted. However, if I use normal cin>>topicClass that is executed. Could you please help me out of this? Thanks
#include <iostream>
#include <string>
using namespace std;
void InfoInput()
{
string classID;
string teacherName;
int totalStudent;
string topicClass;
cout<<"Enter class ID"<<endl;
getline(cin, classID);
cout<<"Enter teacher's name"<<endl;
getline(cin, teacherName);
cout<<"Enter total number of students"<<endl;
cin>>totalStudent;
cout<<"Enter topic of class"<<endl;
getline(cin, topicClass);
//cin>>topicClass;
}
int main ()
{
InfoInput();
}
Your problem is above, with this line:
cin>>totalStudent;
This does not read a line. You enter your input and (I assume) you press ENTER. The \n remains in the buffer of std::cin and is read as an empty line with your next instruction:
getline(cin, topicClass);
To fix, use this code:
cin>>totalStudent;
while(std::isspace(cin.peek())
cin.ignore();
cout<<"Enter topic of class"<<endl;
getline(cin, topicClass);
There is \n remained in cin after reading totalStudent as integer so you need to get that \n first out of the system and then read the next string
#include <iostream>
#include <string>
using namespace std;
void InfoInput()
{
string classID;
string teacherName;
int totalStudent;
string topicClass;
cout<<"Enter class ID"<<endl;
getline(cin, classID);
cout<<"Enter teacher's name"<<endl;
getline(cin, teacherName);
cout<<"Enter total number of students"<<endl;
cin>>totalStudent;
cout<<"Enter topic of class"<<endl;
getline(cin,topicClass);
getline(cin, topicClass);
//cin>>topicClass;
}
int main ()
{
InfoInput();
}
Your classID and teacherName are local variables and disappear after execution leaves the function. You'll have to figure out some way, like passing parameters by reference, to share the variables between functions.
#include <iostream>
#include <fstream>
#include <stdlib.h>
using namespace std;
class Student{
private:
char name[40];
char grade;
float marks;
public:
void getdata();
void display();
};
void Student::getdata(){
char ch;
cin.get(ch);
cout<<"Enter name : ";
cin.getline(name,40);
cout<<"Enter grade : ";
cin>>grade;
cout<<"Enter marks : ";
cin>>marks;
cout<<"\n";
}
void Student::display(){
cout<<"Name : "<<name<<"\t";
cout<<"Grade : "<<grade<<"\t";
cout<<"Marks : "<<marks<<"\t"<<"\n";
}
int main(){
system("cls");
Student arts[3];
fstream f;
f.open("stu.txt",ios::in|ios::out|ios::binary);
if(!f){
cerr<<"Cannot open file !";
return 1;
}
for(int i=0;i<3;i++){
arts[i].getdata();
f.write((char*)&arts[i],sizeof(arts[i]));
}
f.seekg(0); //The question is about this statement;
cout<<"The contents of stu.txt are shown below : \n";
for(int j=0;j<3;j++){
f.read((char*)&arts[j],sizeof(arts[j]));
arts[j].display();
}
f.close();
return 0;
}
The above program reads and writes objects of Student from/to the file "stu.txt".
It runs fine. But it runs fine even if I switch off the fin.seekg(0) statement. I don't understand this part ? Are we not supposed to set the file pointer to the beginning of the file - before starting to read objects from the file(in the context of this particular program)?.
If you are at the end of the file, the read method call will fail, thus the Student structures are left untouched (so you are just printing again the same structures which you left untouched after writing them to file).