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");
}
Related
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.
I have been struggling with a certain error that doesn't make sense to me. Whenever I try to compile this program, it tells me that I'm missing a semicolon when I am not.
It seems the error is linked to a specific block of code, that being the if statement that checks stock. Since I know c++ can be platform specific, I'm running debian 9 and the atom ide if that's any help.
Here is the specifc error:
error: expected primary-expression before ',' token
getline(string,line);//gets string`
and the code:
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
cout << "store stocking system: \n"; // yadda yadda yadda UX
cout << "commands: \n";
cout << " help: shows available commands\n check stock: checks store stock\n enter stock: enter new stock items\n";
cout << " exit: terminates the program\n clean house: deletes all stock\n";
home: // main loop in program
string output;
output = ">> ";
cout << output;
string stock;
string item; // this whole block just defines things and gets input
int itemNumber;
string userInput;
getline(cin,userInput);
if (userInput == "exit")
{
return 0;
}
if (userInput == "enter stock")
{ // enters new stock
cout << "enter item\n>> "; //item name
cin >> item;
cout << "enter amount\n>> "; //amount of item
cin >> itemNumber;
ofstream myfile; //makes file
myfile.open("stock.txt"); //opens myfile
myfile << "\n" << item << "," << itemNumber << "\n"; //writes to file
myfile.close();// closes file
cout << "done";
goto home; //finishes and goes to main loop
}
if (userInput == "check stock") // where the problem is
{
string line;
ifstream file("stock.txt");//checks fo file
file.open("stock.txt");//opens file
getline(string,line);//gets string
file.close();//closes it
cout << line << "\n";
goto home;
}
if (userInput == ""){
goto home;
}
else
{
cout << "\033[1;31mplease use a proper command:\033[0m\n";
goto home;
}
return 0;
}
Are you missing this by any chance?
#include <string>
I believe it simply needs to be getline(file,line) rather than getline(string,line) and then you should be sorted.
string is recognized as a type name, of type std::string which you generously exposed by line using namespace std;. This particular error message is caused by fact that string isn't an expression which can be evaluated . In context of your code it should be
getline(file,line);
PS. Standard would say that you have to include <string> header to use component std::string. Your code compiles thanks to an implementation-defined feature, was imported with <iostream> in this version of header.
I want to be able to loop this file opening and closing to continually search for names.
The first time is no problem and output is what is expected then, when choosing y for yes, an output loop occurs.
Any ideas as to why this would happen? The logic seems more than correct.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string boys, girls, name;
int rank;
char end = 'n';
while (end != 'y' || end != 'Y')
{
cout << "Enter a name to search";
cin >> name;
ifstream input;
input.open("Names2016");
if (input.fail())
cout << "Failed to open file.\n";
while (!input.eof())
{
input >> rank >> boys >> girls;
if (boys == name)
cout << name << " ranks " << rank << " among boys.\n";
if (girls == name)
cout << name << " ranks " << rank << " among girls.\n";
}
input.close();
cout << "Would you like to search another name?\n"
<< "Enter Y for yes or N for no.\n";
cin >> end;
}
return 0;
}
There are a some of things you can do to make this code better,
The first is to use ifstreams and do file input/output the proper idiomatic way in a loop, don't use .eof() to check for end of file in a loop condition (the answer linked in the comments is a good place to start if you want to know why),
The second thing you want to check for validity of the file with a simple if (!file) its much cleaner IMO.
The third thing is, when you have a local file handle like you do in your code, then you can just let it go out of scope and let the destructor cleanup the file and close() it, it's the C++ RAII way of doing things (notice that I have removed the open() method to the constructor call (which does the same thing)
Use cerr instead of cout to report errors
Use char instead of int to represent characters
Not a big change, but using std::toupper like advised in the other answer's comments is a good readable way to check for uppercase and lowercase values at the same time
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string boys, girls, name;
int rank;
char end = 'n';
while (std::toupper(end) == 'Y')
{
cout << "Enter a name to search";
cin >> name;
ifstream input{"Names2016"};
// change here
if (!input) {
cerr << "Failed to open file.\n";
}
while (input >> rank >> boys >> girls)
{
if (boys == name)
cout << name << " ranks " << rank << " among boys.\n";
if (girls == name)
cout << name << " ranks " << rank << " among girls.\n";
}
// change below, just let the file handle go out of scope and close
// input.close();
cout << "Would you like to search another name?\n"
<< "Enter Y for yes or N for no.\n";
cin >> end;
}
return 0;
}
But you can do better on the I/O if your file isn't guaranteed to change over different iterations (in which case you probably need to make sure that there is no race anyway, so I am assuming the file does not change much). Read in the file once and save that information to be used later
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <unordered_map>
#include <vector>
using namespace std;
int main()
{
string boys_name, girls_name, name;
int rank;
char end = 'n';
ifstream input{"Names2016"};
if (!input) {
cerr << "Failed to open file" << endl;
}
// preprocess the information and store it in a map
// making a map from string to vector because it is unclear whether
// there is a 1-1 mapping from the name to the rank for each name
unordered_map<string, vector<int>> boys;
unordered_map<string, vector<int>> girls;
while (input >> rank >> boys_name >> girls_name) {
boys[boys_name].push_back(rank);
girls[girls_name].push_back(rank);
}
while (std::toupper(end) == 'Y')
{
cout << "Enter a name to search";
cin >> name;
// use the map to do the lookup, much faster than reading
// the entire file over and over again
}
return 0;
}
First of all, what is this supposed to mean int end = 'n'; Are you assigning an integer with a character value?!
And why are you opening the same file inside the loop. You should probably open it only once at the beginning of the program.
And the eof doesn't have what to check for, because you have to read from a file to reach its end.
I need to find a string (link name) input by the user in a text file.
How can approach a solution in c++? Do I have to store the file context in structs in order to read the data later? Or can I just open and read the file whenever i want to look for info?
Thank you!
Input file sample
111.176.4.191 www.yahoo.com 01/04/2013
111.176.4.191 www.yahoo.com 01/09/2013
192.168.1.101 www.yahoo.com 01/04/2013
111.176.4.191 www.yahoo.com 01/12/2013
192.168.1.101 www.espn.com 01/05/2013
C++ code
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <string>
using namespace std;
//gobal variables, procedures
void fileinfo1(string);
char IP_Address [12];
char Link_Name [50];
char Date_Accessed [8];
string filename;
int menu;
int main()
{
// the user will input the file name here
cout << "Enter filename> ";
getline( cin, filename );
fstream file( filename.c_str() );
if (!file)
{
cout << "Invalid file.\n";
return EXIT_FAILURE;
}
// the program will display the file context
else
{
string line;
int count = 10;
while ((count > 0) && getline( file, line ))
{
cout << line << '\n';
count--;
}
file.close();
}
return EXIT_SUCCESS;
// The user will be able to choose to see info about all entries or a particular one
cout << "Please select a menu option:";
cout << "1)Link Information in date range";
cout << "2)Information about all links";
cout << "3)Quit the program";
cin >> menu;
switch (menu) {
// see info about a particular link
case 1: fileinfo1(filename);
break;
case 2:
break;
case 3:
break;
default: cout << "Please a choose a number between 1 and 3";
break;
}
// the file is passed to this function
void fileinfo1(string filename) {
//the user will input a link e.g www.espn.com
cout << "What is the link name? ";
cin >> Link_Name;
// and also input date range (start-end)
cout << "What is the starting date? " ;
cin >> Date_Accessed;
cout << "What is the ending date? " ;
cin >> Date_Accessed;
// Now, here's where I'm having trouble
// I need to find the wwww.espn.com in my file based on the range date , so that i will be able to increment the number of hits
unsigned int curLine = 0;
while (getline(filename, line)) { // I changed this, see below
curLine++;
if (line.find(search, 0) != string::npos) {
cout << "found: " << search << "line: " << curLine << endl;
}
}
}
}
Thank you!
This Part of the code shouldnt be written into your main() function.
// the file is passed to this function
void fileinfo1(string filename) {
//the user will input a link e.g www.espn.com
cout << "What is the link name? ";
cin >> Link_Name;
// and also input date range (start-end)
cout << "What is the starting date? " ;
cin >> Date_Accessed;
cout << "What is the ending date? " ;
cin >> Date_Accessed;
// Now, here's where I'm having trouble
// I need to find the wwww.espn.com in my file based on the range date , so that i will be able to increment the number of hits
unsigned int curLine = 0;
while (getline(filename, line)) { // I changed this, see below
curLine++;
if (line.find(search, 0) != string::npos) {
cout << "found: " << search << "line: " << curLine << endl;
}
}
}
and you are using way to many global variables which are really not necessary. And you dident declare the variables line and search. This shoudnt even compile.
Do you want a quick and dirty solution or an elegant one?
For an elegant solution, I would:
Ditch the globals.
Read the entire file into memory before parsing it.
Generate an internal database for your data.
Write a few query functions that return a subset of your data.
For your particular case, you could use a std::multimap < LinkName, DateAndIP > to find all data relating to the link. DateAndIP could be a typedef to std::multimap < Date, IP > . If you've never used multimap, this will be a good learning experience. Write your compare functions and use the find member function to return only what you're looking for.
Good luck and happy coding!
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.