Binary File issues - c++

Hey guys i'm working on this simple bank account program with binary files.
For some odd reason, i can't read from the file. Or to be more on point the program crashes whenever i try to read from the file.
Can someone point me in the right direction? Thank you.
Main.cpp
#include <iostream>
#include<fstream>
#include<cstdlib>
#include "Account_Querry.h"
using namespace std;
int main()
{
Account_Querry Account;
int choice;
cout<<"***Acount Information System***"<<endl;
while(true)
{
cout<<"Select one option below ";
cout<<"\n\t1-->Add record to file";
cout<<"\n\t2-->Show All records in file";
cout<<"\n\t3-->Search Record from file";
cout<<"\n\t4-->Update Record";
cout<<"\n\t5-->Delete Record";
cout<<"\n\t6-->Quit";
cout<<"\nEnter your choice: ";
cin>>choice;
switch(choice)
{
case 1:
Account.write_rec();
break;
case 2:
//Account.search_rec();
break;
case 3:
Account.read_rec();
break;
case 4:
//Account.edit_rec();
break;
case 5:
// Account.delete_rec();
break;
case 6:
exit(0);
break;
default:
cout<<"\nEnter corret choice" << endl;
}
}
system("pause");
return 0;
}
Account_Querry.h
#ifndef ACCOUNT_QUERRY_H
#define ACCOUNT_QUERRY_H
#include <string>
#include <fstream>
class Account_Querry
{
private:
int accountNo;
std::string firstName;
std::string lastName;
double balance;
public:
void setAccountNo(int accountNo);
int getAccountNo();
void setFirstName(std::string firstName);
std::string getFirstName();
void setLastName(std::string lastName);
std::string getLastName();
void setBalance(double balance);
double getBalance();
void read_data();
void show_data();
void write_rec();
void read_rec();
void search_rec();
void edit_rec();
void delete_rec();
};
#endif // ACCOUNT_QUERRY_H
Account_Querry.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <iomanip>
#include <math.h>
#include "Account_Querry.h"
using namespace std;
void Account_Querry::setAccountNo(int accountNo)
{
this->accountNo = accountNo;
}
int Account_Querry::getAccountNo()
{
return accountNo;
}
void Account_Querry::setFirstName(string firstName)
{
this->firstName = firstName;
}
string Account_Querry::getFirstName()
{
return firstName;
}
void Account_Querry::setLastName(string lastName)
{
this->lastName = lastName;
}
string Account_Querry::getLastName()
{
return lastName;
}
void Account_Querry::setBalance(double balance)
{
this->balance = balance;
}
double Account_Querry::getBalance()
{
return balance;
}
void Account_Querry::show_data()
{
cout << "Current Information:" << endl;
cout << "-------------------------------------------------" << endl;
cout << "Name: " << firstName << ' ' << lastName << endl;
cout << "Balance: " << balance << endl;
cout << "ID#: " << accountNo << endl;
cout << "-------------------------------------------------" << endl;
cout << endl;
}
void Account_Querry::read_data()
{
cout<<"\nEnter Account Number: ";
cin>>accountNo;
cin.ignore();
cout<<"Enter First Name: ";
getline(cin,firstName,'\n');
cout<<"Enter Last Name: ";
getline(cin,lastName,'\n');
cout<<"Enter Balance: ";
cin>>balance;
}
void Account_Querry::write_rec()
{
ofstream outfile("record.bank", ofstream::app);
read_data();
outfile.write(reinterpret_cast<char *>(this), sizeof(*this));
outfile.close();
system("cls");
}
void Account_Querry::read_rec()
{
ifstream infile;
infile.open("record.bank", ios::binary);
if(!infile)
{
cout<<"Error in Opening! File Not Found!!"<<endl;
return;
}
cout<<"\n****Data from file****"<<endl;
while(!infile.eof())
{
if(infile.read(reinterpret_cast<char*>(this), sizeof(*this))>0)
{
show_data();
}
}
infile.close();
}

First of all, thanks for posting the whole code.
I just created an empty Visual Studio project in Windows and created the 3 files and copied the code you had posted in your question.
The code seems to execute perfectly fine, although while executing, the Option 2 doesn't show all the records in the file. Option 3 does show all the records in the file. You could update the Options section for that.
Apart from that, I compiled to create 32 bit binaries and 64 bit binaries and both of them seemed to work fine. Option 1 is adding new records and Option 3 is printing all the records. If I try to execute Option 3(show all records) before adding even a single record (delete the bank.record file), it is printing error message as well.
Can you tell how you are compiling the code (VisualStudio/gcc/..) on which OS (Windows/Ubuntu/..)?
Also what inputs are you giving while executing. Are you entering any non-ASCII character names like some Japanese characters?
One suggestion is: Not to dump a class object into a binary file (as done in write_rec). Better create a structure with fixed size variables (not using any string/vector).
For example, instead of string use character array, also instead of vector use static array etc. This will avoid a lot of read back issues.
Hope this helps to resolve your issue.

Related

Why is my program printing the last record of a file twice?

I created a simple bank application program to ask a user whether they want to add a bank record to a file or show all the records available. Both these functions are facilitated by write_rec() and read_rec() respectively. But when the function read_rec() is applied, while it does print all the records available in the file(a single file is used to store all the records), for some reason it prints the last record in the file two times instead of just once. It's very frustrating to see everything works so well then this problem pops up out of nowhere. I tried to see where the issue is but for the life of me I just can't find it. Can you guys please help me with this one?
Here's the code:
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
class account_query
{
char account_number[20];
char firstName[10];
char lastName[10];
float total_Balance;
public:
void set_data();
void show_data();
void write_rec();
void read_rec();
};
void account_query::set_data()
{
cout<<"\nEnter Account Number: ";
cin>>account_number;
cout<<"Enter First Name: ";
cin>>firstName;
cout<<"Enter Last Name: ";
cin>>lastName;
cout<<"Enter Balance: ";
cin>>total_Balance;
cout<<endl;
}
void account_query::show_data()
{
cout<<"Account Number: "<<account_number<<endl;
cout<<"First Name: "<<firstName<<endl;
cout<<"Last Name: "<<lastName<<endl;
cout<<"Current Balance: Rs. "<<total_Balance<<endl;
cout<<"-------------------------------"<<endl;
}
void account_query::write_rec()
{
ofstream outfile;
outfile.open("D:/rec.bin", ios::binary|ios::in|ios::out|ios::app);
set_data();
outfile.write(reinterpret_cast<char *>(this), sizeof(*this));
outfile.close();
}
void account_query::read_rec()
{
ifstream outfile;
outfile.open("D:/rec.bin", ios::binary);
if(!outfile.is_open())
{
cout << "Error! File not found!" << endl;
return;
}
cout << "\n****Data from file****" << endl;
while(outfile.good())
{
outfile.read(reinterpret_cast<char *>(this), sizeof(*this));
show_data();
}
outfile.close();
}
int main()
{
account_query A;
int choice;
cout << "***Account Information System***" << endl;
while(true)
{
cout << "Select one option below";
cout << "\n\t1-->Add record to file";
cout << "\n\t2-->Show record from file";
cout << "\n\t3-->Quit";
cout << "\nEnter you chice: ";
cin >> choice;
switch(choice)
{
case 1:
A.write_rec();
break;
case 2:
A.read_rec();
break;
case 3:
exit(0);
break;
default:
cout << "\nEnter correct choice";
exit(0);
}
}
system("pause");
return 0;
}
And this is the result I get when I try to print the record on the console:
Please help me 🥺
As already pointed out in the comments section, the problem is that the line
while(outfile.good())
will only check whether the stream extraction has already failed. It will not tell you whether the next stream extraction operation will fail or not. It is unable to provide this information.
Therefore, you must check the state of the stream after the attempted stream extraction operation, to see whether it succeeded or not. So you must check the stream state after this line:
outfile.read(reinterpret_cast<char *>(this), sizeof(*this));
It should be checked before you call show_data, because you don't want to call show_data if the stream extraction failed.
The simplest fix would be to change the lines
while(outfile.good())
{
outfile.read(reinterpret_cast<char *>(this), sizeof(*this));
show_data();
}
to the following:
while( outfile.read(reinterpret_cast<char *>(this), sizeof(*this) ) )
{
show_data();
}
This will work because istream::read will return a reference to the stream object outfile and writing
while ( outfile )
is equivalent to
while ( !outfile.fail() )
due to istream::operator bool being called.

Debug Assertion Failed on c++ in run time

I am new to write code in c++ programmıng before I just work on java coding. I try to solve teh txt file as database. But I taken this error I search on internet I cound't find the exact answer ? Please if you know help me. Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void menu() {
puts("1. List the products");
puts("2. Add a new product");
puts("3. Sell the new product");
puts("4. Search by Barcode");
puts("5. Exit");
}
int main(int argc, char *argv[]) {
FILE *fProduct;
char name[20];
int quantity;
int barcode;
double price;
menu();
fProduct = fopen("Product.txt", "a+");
if (fProduct != NULL) {
while (!feof(fProduct))
{
printf("Name :");
scanf("%s" , name);
printf("Quantity :");
scanf("%d", &quantity);
printf("Barcode Number :");
scanf("%d", &barcode);
printf("Price :");
scanf("%lf", &price);
printf("Are there any product ???");
}
}
fclose(fProduct);
}
fclose applied a parameter validation assertion.
The fclose function closes stream. If stream is NULL, the invalid parameter handler is invoked, as described in Parameter Validation. ...
In Debug builds, the invalid parameter macro usually raises a failed assertion and a debugger breakpoint before the dispatch function is called. ...
Move your fclose call to be within the if block that checked for NULL.
Based on your screenshot you have a linker error so you may not be running the correct version of your code. Based on the error message I am guessing that the problem is scanf loading data into the name parameter.
1) do a clean build and make sure you do not get any build or linker errrors.
2) if the error still happens then press retry on the screen and the debugger will show you the line that is causing the problem. Use the stack window to find your code on the stack.
If you want it in C++, it is better to write C++ code instead of C code:
// The headers to include are different
#include <iostream>
#include <fstream>
#include <string>
void menu();
int main() {
using namespace std;
ofstream fProduct;
string name;
int quantity;
int barcode;
double price;
// your menu, but for now we handle only the
// case 2: add a new product.
menu();
// as for now we deal only with the insertion of new
// products
// Let's open a new file using the C++ standard library
fProduct.open("Product.txt", ios::out | ios::app | ios::ate);
// If the write can be opened we continue, otherwise
// we skip the next part of the code
if (fProduct.is_open()) {
string conts = "y";
while (conts == "y") {
cout << "Name: "; cin >> name;
cout << "Quantity: "; cin >> quantity;
cout << "Barcode Number: "; cin >> barcode;
cout << "Price: "; cin >> price;
// Here we write in the file the information the user passed us.
// since we are getting information that should be written as
// sequence of char in the file, we could avoid to use
// int/double variables. Let's write in the file, comma
// separated
fProduct << name << "," << quantity << "," << barcode << "," << price << endl;
// Here we have some way to interrupt the loop
cout << "Add another product? [y/n]";
cin >> conts;
}
// Finally we close the file. (only if it was open...)
fProduct.close();
}
return 0;
}
// Your menu function using the standard streams
void menu() {
using namespace std;
cout << "1. List the products" << endl;
cout << "2. Add a new product" << endl;
cout << "3. Sell the new product" << endl;
cout << "4. Search by Barcode" << endl;
cout << "5. Exit" << endl;
}
and if you want it C it's better to use pure C code:
#include <stdio.h>
#include <string.h>
void menu();
int main() {
FILE *fProduct;
// again, all this variable could be simply char[].
char name[20];
int quantity, barcode;
double price;
// As for now our code handles only the insertion of
// new element, not the other choices of the menu
menu();
// Do not check if it is different than NULL,
// check only if it actually is something...
if (fProduct = fopen("Product.txt", "a")) {
char conts = 'y';
while (conts == 'y') {
printf("Name :"); scanf("%s", name);
printf("Quantity :"); scanf("%d", &quantity);
printf("Barcode Number :"); scanf("%d", &barcode);
printf("Price :"); scanf("%lf", &price);
// Let's write in the file
fprintf(fProduct, "%s,%d,%d,%lf\n", name, quantity, barcode, price);
getchar(); // chomps the last newline
printf("Add another product? [y/n] ");
conts = getchar();
}
// At the end of our loop we need to close the file.
fclose(fProduct);
}
return 0;
}
void menu() {
puts("1. List the products");
puts("2. Add a new product");
puts("3. Sell the new product");
puts("4. Search by Barcode");
puts("5. Exit");
}

What is wrong with this code? I'm new to c++!

#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
class UserBase{
public:
void GetUsername(string GetName){
MyUserName = GetName;
}
void GetPassword(string GetPassword){
GetPassword = MyPassword;
}
private:
string MyUserName;
string MyPassword;
};
int main(){
UserBase Input;
string MyName;
string MyPassword;
Input.GetUsername("test");
Input.GetPassword("noob");
cout << "enter your username, please." << endl;
cin >> MyName;
if (MyName == Input.GetUsername){
cout << "enter your password.." << endl;
cin >> MyPassword;
if (MyPassword == Input.GetPassword){
cout << "login was successfull" << endl;
Sleep(5000);
}
}
return 0; // if 0 then its a success
}
//so basically im trying to make a username and login password application. i am new to c++, i have only coded for 3 weeks and im just toying around. whenever i try to run it says that there were erros, but it didnt show me where and no red whatsoever.i use vs 2013.
here, I corrected it. Lot's of mistakes.
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
class UserBase{
public:
string GetUsername(){
return MyUserName;
}
string GetPassword(){
return MyPassword;
}
void setUsername(string name){
MyUserName = name;
}
void setPassword(string password){
MyPassword = password;
}
private:
string MyUserName;
string MyPassword;
};
int main(){
UserBase Input;
string MyName;
string MyPassword;
Input.setUsername("test");
Input.setPassword("noob");
cout << "enter your username, please." << endl;
cin >> MyName;
if (MyName == Input.GetUsername()){
cout << "enter your password.." << endl;
cin >> MyPassword;
if (MyPassword == Input.GetPassword()){
cout << "login was successfull" << endl;
Sleep(5000);
}
}
return 0; // if 0 then its a success
}
you had no real getPassword, getUsername, you only had setters (wich are called get... wich is confusing !!). You also called "getPassword" (in wrong context) with wrong syntax.
getPassword; //wrong
getPassword(); //correct
You have
if (MyName == Input.GetUsername)
But GetUsername is not a valid method call firstly, and anyways, GetUsername() returns void, where you're expecting to compare to a string MyName. Also, because the two strings within the class are private access, you don't have a way of accessing them at all outside of the class, in your main function. If you added a getter method like string getUsername() const which returned the correct string inside, then you could compare to this.

FileObject reads input that is not in file, c++

I'm working on this program that is supposed to read data from a file that is formatted like the following, Code#Salary. The user is supposed to give a code, the program should find that code in the file if it exists and then return the salary. However, when I run the program, I keep getting a salary that is not even one of the options.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
int code;
double salary;
int name;
ifstream inFile;
inFile.open("/Users/rsoni613/Desktop/payroll.txt");
if (inFile)
{
cout << "Enter payroll code: ";
cin >> code;
do
{
inFile >> name;
}
while (code != name);
inFile.ignore('#');
inFile >> salary;
inFile.close();
cout << "Salary: $" << salary << endl;
}
else
{
cout << "File did not open, please retry.";
}
return 0;
}
Here are the contents of input file, payroll.txt
1#23400
4#17000
5#21000
6#12600
9#26700
10#18900
11#18500
13#12000
15#49000
16#56500
20#65000
21#65500
22#78200
23#71000
24#71100
25#72000
30#83000
31#84000
32#90000
double salary;
variable salary is of type double. No wonder you are getting different result.

c++Bank project; How to read a set of strings as individual floats and add them

Problem statement:
C++ program that reads a customer’s checking account information calculates his/her account balance.
menu based application should be
developed to perform the following
functionalities iteratively until the user request to quit the program:
1. Display, 2. Deposit, 3. Withdraw, 4. Quit.
This is what I have so far.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
//Main function
int main()
{
//Identify type variables
int x=0;
float amountinput,famount,sum;
string firstname, lastname,date,filename,input,ID,amount;
fstream file;
//Program loop
while(true)
{
//Main menu loop
do
{
cout<<"Enter the number of the option you would like carried out.\n";
cout<<"1. Summary\n";
cout<<"2. Deposit\n";
cout<<"3. Withdraw\n";
cout<<"4. Quit\n";
cin>>x;
}
while(!x);
//When Quit is input, break
if(x==4)
{
break;
}
//Summary display
if (x==1)
{
cout<<"You have selected option number 1. Summary.\n"<<endl;
cout<<"Enter your Cust_ID: ";
cin>>ID;
file.open("C:\\Users\\Raggulddon\\Desktop\\C++ supplement
\\Cust_"+ID+".dat", ios::in|ios::out|ios::app);
//IF not found error.
if(!file)
{
cout<<"Sorry your account could not be found\n";
}
//Else display all content.
else
{
cout<<endl<<file.rdbuf()<<"\n";
file.close();
}
}
//Deposit
else if(x==2)
{
cout<<"You have selected option number 2. Deposit.\n";
cout<<"Please enter you account ID: ";
cin>>ID;
file.open("C:\\Users\\Raggulddon\\Desktop\\C++ supplement
\\Cust_"+ID+".dat", ios::in|ios::out|ios::app);
if(!file)
{
cout<<"Sorry the requested account could not be located.\n";
}
else
{
file>>firstname>>lastname;
cout<<endl<<firstname<<" "<<lastname<<endl;
while(!file.eof())
{
file>>date>>amount;
//
//This is mainly where I am missing the lines of code..
//
float atof(string& amount);
cout<<date<<"\t\t"<<amount<<endl;
}
cin.get();cin.get();
cout<<"How much would you like to deposit today.";
cin>>amountinput;
cout<<endl;
file.close();
}
}
else if(x==3);
else if(x==4);
}
cin.get();cin.get(); //or system("PAUSE");
return 0;
}
A sample text file looks like this.
James Bond
01/01/12 200010
03/30/12 -40000
04/30/12 -40000
05/30/12 -40000
06/30/12 -40000
07/30/12 -40000
I have converted the date and amount into strings and have attempted
to convert it into a float and double, and add them up.
I have thought of separating the amounts but I can't manage to do that either.
I have also tried to make make amount a char type.
Any advice to lead me on the right path would be kindly appreciated.
Although it doesn't attempt to be a complete version of your program, here's a bit of code to read the supplied text file, using the first item (after the name) as an initial balance, and the rest as deposits (if they're positive) or withdrawals (if they're negative), reporting the amount of each transaction, and the balance after it's been applied.
#include <iostream>
#include <string>
#include <algorithm>
struct transaction {
std::string date;
double value;
friend std::istream &operator>>(std::istream &is, transaction &t) {
is >> t.date >> t.value;
return is;
}
operator double() { return value; }
};
int main(){
double value;
transaction t;
std::string name;
std::getline(std::cin, name);
std::cin >> t;
value = t;
while (std::cin >> t) {
std::cout << "Transaction: " << t.value;
value += t;
std::cout << "\tBalance: " << value << "\n";
}
std::cout << value;
}