void adding();
void print();
void end();
int counter = 0;
int main()
{
char choice;
cout << "What do you want to do?" << endl;
cout << "a = add a student, p = print the student list, e = exit function" << endl;
cin >> choice;
switch (choice) {
case 'a':
adding();
break;
case 'p':
print();
break;
case 'e':
end();
break;
default:
cout << "That is not a valid option.";
break;
}
}
void adding()
{
ofstream outFS;
outFS.open("myoutfile.txt", fstream::app);
int i = 0;
string name[100]; string amount[100]; string grades[100];
for (i = 0; i < 1; i++) {
cout << "What is the name of the student?";
cin >> name[i];
outFS << name[0] << ' ';
cout << "How many exercises has the student completed?";
cin >> amount[i];
outFS << amount[0] << ' ';
cout << "What grade did the student get?";
cin >> grades[i];
outFS << grades[0] << ' ';
counter++;
}
outFS.close();
main();
}
void print()
{
ifstream inFS;
inFS.open("myoutfile.txt");
string name;
inFS >> name;
int amount;
inFS >> amount;
int grades;
inFS >> grades;
inFS.close();
cout << name << ' ' << amount << ' ' << grades << endl;
main();
So when I use the "adding" function it works fine and adds it to the file. When I add the more than one student the file still shows it but when I print within the console it only prints out the first student and their info. How do I get it to show the entire array in the console? I tried to use a counter variable but it is not helping
What you are missing is the loop keywords (the various incarnations of for and while).
Making your own loop by doing this:
void a()
{
// Do stuff
b();
}
void b()
{
// Do other stuff
a();
}
Is really not a good idea since it will just throw more and more calls on the stack, and eventually make the stack run out of space (which will crash the program). Replacing one of those functions with main() is even worse, because main() is a special function that you really are not allowed to call yourself.
Instead do something like this:
int main()
{
char choice;
bool running = true;
while (running)
{
cout << "What do you want to do?" << endl;
cout << "a = add a student, p = print the student list, e = exit function" << endl;
cin >> choice;
switch (choice) {
case 'a':
adding();
break;
case 'p':
print();
break;
case 'e':
// end(); Dunno what this does. Is it just an empty function that will finally end the infinite stack of calls?
// I am replacing it with setting the loop variable to false, which will stop the loop
running = false;
break;
default:
cout << "That is not a valid option.";
break;
}
}
}
Then remove all calls to main() from the rest of your code.
As for your print() function, again your problem is the lack of loops. Your current code opens the file, reads the first line, prints the line, then closes the file and calls main. Then the next time print() is called it again opens the file, reads the first line, etc.
What you need is a loop that reads all the lines before closing the file again. Something like this should do the trick:
void print()
{
ifstream inFS;
inFS.open("myoutfile.txt");
string name;
int amount;
int grades;
while (inFS >> name >> amount >> grades)
{
cout << name << ' ' << amount << ' ' << grades << endl;
}
inFS.close();
}
However, all of this is pretty basic C++ that should have been covered in whatever book you are using to learn C++. And if you do not have a C++ book to learn from, then I strongly recommend that you get one - it will be only get harder to learn if you constantly get stuck on basic stuff.
Related
Function 5:
The Display Sales History Function.. It is just displaying the last entry twice...
Function 1:
The 'Add Book' Feature.. It was actually working alright until I added the 'Edit Book' and 'Add Sales' Features. Now it writes something to the file("Books.txt"); that none of the other functions identify. Earlier,i.e.
when 'Edit Book' and 'Add Sales' weren't coded and structure Sale not declared,
'Search Book' could work properly with the entry done by 'Add Book'.
((This is what I found in BOOKS.txt when I only coded functions 1 and 2 and did a test run:
{{Mein Kampf ÿu)<èÿX 0# Ÿ0 :òÿ2 XThe Accidental Prime Minister Ÿ0 :òÿ< ^Quantico ental Prime Minister Ÿ0 :òÿ ÂSurely You Are Joking, Mr. Feynman X0- ô}}
If you paste this in Books.txt, all features except 'Add' work allright))
#include <fstream.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
struct Sale {
char costumer[40], name[40];
int quant, pric, netprice;
};
class Book {
public:
char name[40];
int qty, code, price;
void Add()
{
cout << "\n Enter Name Of New Book\n";
gets(name);
cout << "\n Enter book code:";
cin >> code;
cout << "\n Enter book price:";
cin >> price;
cout << "\n Enter book quantity:";
cin >> qty;
}
void Display()
{
cout << "\n Name:";
puts(name);
cout << "Code:" << code;
cout << "\nPrice:" << price;
cout << "\nQuantity Available:" << qty;
}
void Modify();
Sale Sell(int q)
{
Sale sale;
sale.pric = price;
qty -= q;
sale.quant = q;
sale.netprice = q * price;
cout << "\n Enter costumer name\n";
gets(sale.costumer);
strcpy(sale.name, name);
return sale;
}
};
void Book::Modify()
{
Display();
char ch = 'n';
do {
cout << "\n Enter detail to modify \n";
cout << "1.NAME\t2.QUANTITY\t3.CODE\t4.PRICE\n";
int mod;
cin >> mod;
switch (mod) {
case 1:
cout << "\nEnter new Name\n";
gets(name);
break;
case 2:
cout << "\nEnter new available quantity\n";
cin >> qty;
break;
case 3:
cout << "\nEnter changed CODE\n";
cin >> code;
break;
case 4:
cout << "\nEnter updated PRICE\n";
cin >> price;
break;
}
Display();
cout << "\nWant to edit more? (y/n)\n";
ch = getch();
} while (ch == 'y' || ch == 'Y');
}
void Print(Sale s)
{
cout << "\nCostumer Name:\t";
puts(s.costumer);
cout << "Book Name:\t";
puts(s.name);
cout << "\nQuantity(units):" << s.quant << "\tPrice per pice:" << s.pric << "\n\t Net Sale:" << s.netprice;
}
void MScreen()
{
clrscr();
cout << "\tTHE BOOK STORE MANAGEMENT SOFTWARE\n";
cout << "\tPLEASE CHOOSE AN OPTION";
cout << "\n1.ADD NEW BOOK\n2. SEARCH FOR A BOOK\n3. EDIT BOOK DETAILS\n 4.ADD NEW SALES\n5. DISPLAY SALES HISTORY\n";
}
void main()
{
char ch = 'n';
while (ch == 'n' || ch == 'N') {
MScreen();
int i;
cin >> i;
clrscr();
switch (i) {
case 1:
Book a;
a.Add();
ofstream obj1("BOOKS.txt", ios::app);
obj1.write((char*)&a, sizeof(Book));
obj1.close();
break;
case 2:
Book b;
ifstream obj2("BOOKS.txt");
obj2.seekg(0);
cout << "Enter Book Code:";
long int x;
cin >> x;
while (!obj2.eof()) {
obj2.read((char*)&b, sizeof(Book));
if (b.code == x) {
b.Display();
obj2.close();
break;
}
}
break;
case 3:
Book c;
cout << "\n Enter Code of book to be modified\t";
int y;
cin >> y;
fstream obj3("BOOKS.txt", ios::in | ios::out | ios::ate);
long int pos;
obj3.seekg(0);
while (!obj3.eof()) {
pos = obj3.tellg();
obj3.read((char*)&c, sizeof(Book));
if (c.code == y) {
c.Modify();
obj3.seekp(pos);
obj3.write((char*)&c, sizeof(Book));
break;
}
}
cout << "\nDATA MODIFIED\n";
break;
case 4:
char ch1 = 'n';
do {
Book d;
cout << "\n Enter the book code \t";
int z;
cin >> z;
fstream obj4("BOOKS.txt", ios::in | ios::out | ios::ate);
long int pos;
obj4.seekg(0);
int found = 0;
while (!obj4.eof()) {
pos = obj4.tellg();
obj4.read((char*)&d, sizeof(Book));
if (d.code == z) {
found = 1;
break;
}
}
if (found == 0) {
cout << "\nIncorrect Code\t Aborting";
break;
}
else {
d.Display();
cout << "\nEnter Sales Quantity:\t";
int q;
cin >> q;
if (q > d.qty) {
cout << "\n Can't Sell. Aborting ";
break;
}
else {
Sale newsale;
newsale = d.Sell(q);
obj4.seekp(pos);
obj4.write((char*)&d, sizeof(Book));
obj4.close();
ofstream obj5("Sales.txt", ios::app);
obj5.write((char*)&newsale, sizeof(newsale));
obj5.close();
cout << "\nSALE SUCCESSFUL\n";
sleep(2);
}
}
cout << "\n Add more sale? (y/n)";
cin >> ch1;
} while (ch1 == 'y' || ch1 == 'Y');
break;
case 5:
cout << "\nPlease enter SALE password:";
char pass[40];
gets(pass);
if (strcmp(pass, "creationbydhruvarora\n")) {
clrscr();
ifstream obj6("Sales.txt");
obj6.seekg(0);
Sale readsale;
int net = 0;
while (!obj6.eof()) {
obj6.read((char*)&readsale, sizeof(Sale));
net += readsale.netprice;
Print(readsale);
sleep(1);
}
cout << "\n END OF SALES\n TODAY NET SALE:" << net;
break;
}
else {
cout << "\nIncorrect Password\n ABORTING";
break;
}
}
getch();
clrscr();
cout << "Press Any Key To QUIT. To Go To Main Menu Press 'n'\n";
ch = getch();
}
}
I do not understand what this is. A piece of code added to some code is disrupting working w/o being executed.
First, you are using stuff that's seriously ancient. There is free, absolutely, completely, and totally free stuff out there that's much more modern than this. If this is production code, you should be moving it to a newer platform. If it's student code, you shouldn't be learning on this platform at all. If you have at least an 80386, there are perfectly serviceable tiny Linux distributions available for free download that will run on the hardware you have. And then you'll have a modern compiler.
You clearly have access to the Internet, so you should have some ability to do this. In fact, the hardware you're using to access this site could probably run a modern, completely free to use compiler like GNU C++ or clang.
I can tell from the headers and lack of ::std namespace you have that you're using a really old MS-DOS based compiler. Turbo C++, Borland C++, Zortech C++, maybe whatever Microsoft called their thing back then. Something like that. I know because I've written C++ for that platform... in 1990.
Even given that ancient platform, your code is written poorly. You are mixing stdio and iostreams. While this isn't inherently bad, it's confusing. Additionally, you're using gets which makes it easy for bad input to crash your program. There are other problems, but I won't get into all of them because I don't think they're relevant to your question.
The reason, in general, why adding code that's never executed causes your program to crash is that it had an already existing problem that moving stuff around in memory made appear. I can't compile or run your code because it's too ancient. Additionally, I have no available input to use.
But, were I to hazard a guess, it would be because you are using gets and the input is causing a buffer overrun (you are reading more than 40 characters into your buffer). It always caused a buffer overrun, but because the new code moved stuff around in memory, it's now causing your program to crash instead of having no effect or causing some other problem you didn't see before. Buffer overruns result in undefined behavior, which means the program is allowed to do anything, even seemingly work perfectly normally.
Here is a function to replace all your gets calls with:
int fetch_line(char *s, int size)
{
fgets(s, size, stdin);
if ((size <= 0) || (s[0] == '\0') || (s[strlen(s) - 1] != '\n')) {
int c = '\0';
do {
c = getchar();
} while ((c != '\n') && (c != EOF));
return c != EOF;
} else {
s[strlen(s) - 1] = '\0'; // Drop trailing newline.
}
}
This function will return a non-zero (aka true) value if it did not encounter EOF and 0 (aka false) if it did. It will discard any characters that don't fit in your buffer but still read until the end of line (aka '\n') character. In your code, a call to it would look like fetch_line(name, sizeof(name));.
Your code may have other problems, but if it does, they aren't obvious to me. The gets one is a huge red flag though. You should never use gets. My compiler gives me scary deprecation warnings that I can't turn off if I use it because the call is going away completely in a few years.
In general, any function that works with C-style strings and doesn't have a parameter declaring the maximum size of any string being written to is a bad function to use that's prone to buffer overrun behavior.
BTW, I have no platform on which calls to getch or clrscr work anymore. Using those functions makes your program very non-portable.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm working on a project, to create a linked list in class but I can't even start working on it because every time I run the program it's will stop working when I want to input data.
Can someone tell me how to input data properly using class? and if possible please let me know how to improve this program. The code that I've done is quite long.
I'll try to make it short and simple for you guys to understand. A lot of people been suggesting me to use std::string but our lecturer never mentioned about it so we have no idea how to use it.
If I have to use it that means I have to start learn it from the beginning which means it will take time for me to really understand it.
We're also required to have a function where we can update the data stored, search the data based on one of its data and make a summary for it.
#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include <conio.h>
#include <stdio.h>
#include <string>
using namespace std;
//CLASS USED IN PROGRAM
class carInsurance
{
private:
int total;
int customerNo;
string name;
string iCno;
char dob[10];
string nationality;
string address;
char phoneNo[15];
string email;
string occupation;
char carNo[10];
char expireDate[11];
float insuranceAmount;
char carUsage[30];
char manufacturingDate[11];
int package;
int option;
int additional;
int noCustomer[10];
public:
void add();
void presetdata();
static void deleteFunc(carInsurance noCustomer[]);
static void viewAll(carInsurance noCustomer[]);
//constructor name has to be the same as class
carInsurance(int carInsurance_total,
int carInsurance_customerNo,
string carInsurance_name,
string carInsurance_iCno,
char carInsurance_dob[10],
string carInsurance_nationality,
string carInsurance_address,
char carInsurance_phoneNo[15],
string carInsurance_email,
string carInsurance_occupation,
char carInsurance_carNo[10],
char carInsurance_expireDate[11],
float carInsurance_insuranceAmount,
char carInsurance_carUsage[30],
char carInsurance_manufacturingDate[11],
int carInsurance_package,
int carInsurance_option,
int carInsurance_additional)
{
total = carInsurance_total;
customerNo = carInsurance_customerNo;
name = carInsurance_name;
iCno = carInsurance_iCno;
dob[10] = carInsurance_dob[10];
nationality = carInsurance_nationality;
address = carInsurance_address;
phoneNo[15] = carInsurance_phoneNo[15];
email = carInsurance_email;
occupation = carInsurance_occupation;
carNo[10] = carInsurance_carNo[10];
expireDate[11] = carInsurance_expireDate[11];
insuranceAmount = carInsurance_insuranceAmount;
carUsage[30] = carInsurance_carUsage[30];
manufacturingDate[11] = carInsurance_manufacturingDate[11];
package = carInsurance_package;
option = carInsurance_option;
additional = carInsurance_additional;
} // end of constructor
carInsurance()
{ // Set all variables to null
total = 0;
customerNo = 0;
name = " ";
iCno = " ";
dob[10] = '\0';
nationality = " ";
address = " ";
phoneNo[15] = '\0';
email = " ";
occupation = " ";
carNo[10] = '\0';
expireDate[11] = '\0';
insuranceAmount = 0;
carUsage[30] = '\0';
manufacturingDate[11] = '\0';
package = 0;
option = 0;
additional = 0;
}
// SET
void setChar(char carInsurance_dob[10],
char carInsurance_phoneNo[15],
char carInsurance_carNo[10],
char carInsurance_expireDate[10],
char carInsurance_carUsage[30],
char carInsurance_manufacturingDate[10])
{dob[10] = carInsurance_dob[10];
phoneNo[15] = carInsurance_phoneNo[15];
carNo[10] = carInsurance_carNo[10];
expireDate[11] = carInsurance_expireDate[11];
carUsage[30] = carInsurance_carUsage[30];
manufacturingDate[11] = carInsurance_manufacturingDate[11];}
void setname(string carInsurance_name){name = carInsurance_name;}
void setiCno(string carInsurance_iCno){iCno = carInsurance_iCno;}
void setAddress(string carInsurance_address){address = carInsurance_address;}
void setString(string carInsurance_nationality, string carInsurance_email,string carInsurance_occupation)
{nationality = carInsurance_nationality; email = carInsurance_email; occupation = carInsurance_occupation;}
void setInt(int carInsurance_total, int carInsurance_customerNo, int carInsurance_package, int carInsurance_option, int carInsurance_additional)
{customerNo = carInsurance_customerNo; package = carInsurance_package; option = carInsurance_option; additional = carInsurance_additional;}
void setFloat (float carInsurance_insuranceAmount){insuranceAmount = carInsurance_insuranceAmount;}
// GET
string getname(){return name;}
string getiCno(){return iCno;}
string getaddress(){return address;}
string getString(){return nationality; return email; return occupation;}
int getInt(){return total; return customerNo; return package; return option; return additional;}
float getFloat(){return insuranceAmount;}
}; //end class
Here goes my main:
//function declaration
//to prevent overload run function outside
void add();
//THE MAIN FUNCTION OF PROGRAM
int main()
{
carInsurance obj; // obj is class object
carInsurance *noCustomer[10];
int choice;
while(choice != 4)
{
cout << "1. ADD, UPDATE, DELETE\n" << "2. SEARCH\n" << "3. VIEW ALL\n" << "4. SUMMARY REPORT\n" << "5. EXIT\n" << endl;
cout << "Enter your choice: ";
cin >> choice;
system("cls");
switch(choice)
{
case 1:
{
cout << "___________________________________\n";
cout << "\n\tADD/UPDATE/DELETE\n";
cout << "___________________________________\n";
cout << "\n1. ADD\n2. UPDATE\n3. DELETE\n" << endl;
cin >> choice;
system("cls");
switch(choice)
{
case 1:
{
int i;
int total = 0;
cout << "How many customer? ";
cin >> total;
for(i=0; i<total; ++i)
{
cout << "________________________________\n";
cout << "\n\tCUSTOMER NO. " << 1 + i;
cout << "\n________________________________\n";
noCustomer[i]->add(); // this is function call to input
}
break;
}
case 2:
{
int paymentID;
//cout << "UPDATE" << endl;
cout << "\nEnter the customer ID that you want to update:";
cin >> paymentID;
// function here
break;
}
case 3:
{
int paymentID;
//cout << "DELETE" << endl;
cout << "\nEnter the customer ID that you want to delete:";
cin >> paymentID;
noCustomer[10]->deleteFunc(noCustomer[10]);
break;
}
} // End of switch case for add,update,delete
system("cls");
break;
} // End of case 1
case 2:
{
cout << "___________________________\n";
cout << "\n\t SEARCH\n";
cout << "___________________________\n";
system("pause");
system("cls");
break;
}
case 3:
{ cout << "___________________________\n";
cout << "\n\tVIEW ALL\n";
cout << "___________________________\n";
obj.presetdata();
noCustomer[10]->viewAll(noCustomer[10]);
cout<<"\n";
system("pause");
system("cls");
break;
}
case 4:
{
cout << "___________________________\n";
cout << "\n\tSUMMARY REPORT\n";
cout << "___________________________\n\n";
cout << "1. Sorted by different month\n2. Sorted by different car type\n3. Sorted by different insurance" << endl;
cin >> choice;
switch(choice)
{
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
default:
cout << "Wrong input! Please choose again: ";
cin >> choice;
system("pause");
}
break;
}
case 5:{
cout << "___________________________\n";
cout << "\n\tTHANK YOU!\t\n";
cout << "___________________________";
exit(0); }
default:
continue;
}// End of switch case
}// End of while
return 0; //indicates success
}//End of main
I see a problem in the inner switch statement:
case 1:
{
int i;
int total = 0;
cout << "How many customer? ";
cin >> total;
for(i=0; i<total; ++i)
{
cout << "________________________________\n";
cout << "\n\tCUSTOMER NO. " << 1 + i;
cout << "\n________________________________\n";
noCustomer[i]->add(); // this is function call to input
break;
}
}
case 2:
The break operator breaks the loop, but does not prevent executing case 2: branch.
Yet another problem: re-assignment of choice. User may input 4 in any input request that will break while (choice != 4) unexpectedly. You can avoid troubles with break and re-assignments by using functions.
There is a lot of out of array bounds access by indexes that are equal to array sizes.
It is not clear what you want to reach in dob[10] = carInsurance_dob[10]; It copies 11th char. Maybe you want to copy the whole char array. Use std::string for error-free code.
I am having an issue when trying to use a getline command where a user can enter in a movie and then add to the collection of movies (stored in "movies.txt")
My code is compiling, but it starts out with the 3rd case automatically. When I press "q" to quit that case, it reverts to the menu, yet when I try and write out the file or print the collection, no movie titles have been saved. Where I should go from here? I feel like I'm on the cusp of understanding this.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int ARRAY_SIZE = 200;
string movieTitle [ARRAY_SIZE];
int loadData (string pathname);
int writeData (string pathname);
int getTitle (string movieTitle[]);
void showAll (int count);
int main()
{
loadData("movies.txt");
char userInput;
string movieTitle[ARRAY_SIZE];
int count = getTitle(movieTitle);
bool endOfProgram = false;
while (endOfProgram ==false)
{
cout << "1. Read in Collection" << endl;
cout << "2. Print Collection" << endl;
cout << "3. Add a Movie to the Collection" << endl;
cout << "4. Write out Collection" << endl;
cout << "5. Quit the Program" <<endl;
cin >> userInput;
switch(userInput)
{
case('1'):
{
loadData("movies.txt");
break;
}
case('2'):
{
showAll(loadData("movies.txt"));
break;
}
case('3'):
{
cout << getTitle(movieTitle);
break;
}
case('4'):
{
cout <<"Write out Collection" << endl;
writeData("movies.txt");
break;
case('5'):
{
endOfProgram=true;
cout << "Have a nice day" <<endl;
break;
}
}
}
}
}
int loadData (string pathname)
{
int count = 0;
ifstream inFile;
inFile.open(pathname.c_str());
if (!inFile)
return -1;
else
{
while(!inFile.eof())
{
getline(inFile, movieTitle[count]);
count++;
}
}
return count;
}
int writeData (string pathname)
{
ofstream outfile;
outfile.open("movies.txt");
if(!outfile.is_open())
{
cout << "Cannot open movies.txt" << endl;
return -1;
}
outfile.close();
return 0;
}
void showAll (int count)
{
cout << "\n";
for (int i=0; i< count; i++)
{
cout << movieTitle[i] << endl;
}
cout << "\n";
}
int getTitle (string movieTitle[])
{
string movie;
int count = 0;
while(true)
{
cout <<"Enter Movie Titles (Type 'q' to quit)" <<endl;
cin >> movie;
if (movie == "q")
{
break;
}
movieTitle [count] = movie;
count++;
}
return count;
}
I believe cin reads until eol is found, i.e. the user presses return.
So look for integer in the userInput variable, and pass that to your switch statement
int nr = atoi(userInput.c_str())
switch(nr){
case 1:
case 2: etc ...
In your codes it is not clear why it directly goes to case '3'. It should wait for a user input first. Seems like something already available in buffer. Just put one cout statement in case '3': and check what it print. If possible put break point there and run the application in debug mode and check the value. Hope this will help you.
case('3'):
{
cout<<"Value of userInput is: "<<userInput<<endl;
cout << getTitle(movieTitle);
break;
}
Alternately you can add the below line of code just before cin like below
std::cin.clear();
cin >> userInput;
I recommend inputting an integer instead of a character for your input.
You will need to change the case values too:
int selection = 0;
//...
cin >> selection;
switch (selection)
{
case 1:
//...
}
You won't have to worry about characters in the buffer. The stream will fail if an integer is not read.
I have written this code and I am supposed to read in a txt file and read every other line in the txt file to the string array bookTitle[ARRAY_SIZE] and the other every other line to bookAuthor[ARRAY_SIZE]. Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int ARRAY_SIZE = 1000;
string bookTitle [ARRAY_SIZE];
string bookAuthor [ARRAY_SIZE];
int loadData(string pathname);
void showAll(int count);
//int showBooksByAuthor (int count, string name);
//int showBooksByTitle (int count, string title);
int main ()
{
int number, numOfBooks;
char reply;
string bookTitles, authorName, backupFile;
cout << "Welcome to Brigham's library database." << endl;
cout << "Please enter the name of the backup file:";
cin >> backupFile;
numOfBooks = loadData (backupFile);
if (numOfBooks == -1) {
cout << endl;
} else {
cout << numOfBooks << " books loaded successfully." << endl;
}
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All:";
cin >> reply;
do {
switch (reply) {
case 'a':
case 'A':
cout << "Author's name: ";
cin >> authorName;
showBooksByAuthor (numOfBooks, authorName);
cout << endl;
break;
case 'q':
case 'Q':
cout << endl;
break;
case 's':
case 'S':
showAll(numOfBooks);
break;
case 't':
case 'T':
cout << "Book title: ";
cin >> bookTitles;
showBooksByTitle(numOfBooks, bookTitles);
cout << endl;
break;
default:
cout << "Invalid input" << endl;
break;
}
} while (reply != 'q' && reply != 'Q');
while (1==1) {
cin >> number;
cout << bookTitle[number] << endl;
cout << bookAuthor[number] << endl;
}
}
int loadData (string pathname){
int count = 0, noCount = -1;
ifstream inputFile;
string firstLine, secondLine;
inputFile.open(pathname.c_str());
if (!inputFile.is_open()) { //If the file does not open then print error message
cout << "Unable to open input file." << endl;
return noCount;
}
for (int i = 0; i <= ARRAY_SIZE; i++) {
while (!inputFile.eof()) {
getline(inputFile, firstLine);
bookTitle[i] = firstLine;
getline(inputFile, secondLine);
bookAuthor[i] = secondLine;
cout << bookTitle[i] << endl;
cout << bookAuthor[i] << endl;
count++;
}
}
return count;
}
void showAll (int count) {
for (int j = 0; j <= count; j++) {
cout << bookTitle[j] << endl;
cout << bookAuthor[j] << endl;
}
}
So I have the loadData function which I am pretty sure is my problem. When I have it print out each string[ith position] while running the loadData function it prints out each title and author just as it appears in the txt file. But then when I run the void showAll function which is supposed to be able to print the entire txt doc to the screen it doesn't work. Also just I checked to see if the strings were actually stored in memory and they were not. (After my do while loop I have a while loop that accepts input of type int and then prints the string array of the [input position]. This prints nothing. So what do I have to do to actually store each line to a different position in the string array(s)? Feel free to correct my code but it isn't pretty yet considering I still have two functions that I haven't done anything too. (Commented out).
You main problem is that you try to read you data using two loops rather than just one! You want read until either input fails or the array is filled, i.e., something like this:
for (int i = 0;
i < ARRAY_SIZE
&& std::getline(inputFile, bookTitle[i])
&& std::getline(inputFile, bookAuthor[i]); ++i) {
}
The problem with the original code is that it never changes the index i and always stores values into the cell with index 0. Since the input isn't checked after it is being read, the last loop iteration fails to read something and overwrites any earlier stored value with an empty value. Once reading of the stream fails the outer loop iterates over all indices but doesn't do anything as the check to the inner loop is always false.
For some reason my bank script isn't working. More specifically, the search() does not work. I kind of understand why it doesn't, probably because of if(obj.returnId() == n), but I have no clue how to fix it. When I search an account, it will only allow me to find the last account made, not any of the previous ones. Here is my code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <string.h>
#include <fstream>
#include <Windows.h>
#include <conio.h>
using namespace std;
bool loop = true;
class account
{
int id;
char name[40];
char password[40];
public:
void getData()
{
cout << "\nEnter your name: ";
cin >> name;
cout << "\nEnter ID: ";
cin >> id;
cout << "\Enter pass: ";
cin >> password;
}
void showData()
{
cout << "\nName: ";
puts(name);
cout << "\nID: " << id;
cout << "\n";
}
int returnId()
{
return id;
}
};
void createAccount()
{
account obj;
ofstream fileCreate;
fileCreate.open("accounts.dat", ios::binary|ios::app);
obj.getData();
fileCreate.write((char*)&obj,sizeof(obj));
fileCreate.close();
}
void display()
{
account obj;
ifstream fileRead;
fileRead.open("accounts.dat", ios::binary);
while(fileRead.read((char*)&obj, sizeof(obj)))
{
obj.showData();
}
fileRead.close();
}
void search(int n)
{
account obj;
ifstream fileRead;
fileRead.open("accounts.dat", ios::binary);
while(fileRead.read((char *) &obj, sizeof(obj)) );
{
fileRead.seekg(0,ios::beg);
if(obj.returnId() == n)
{
obj.showData();
}
else {
cout << "\nUser not foud!\n";
}
}
fileRead.close();
}
void main()
{
cout << "Welcome to the Bank.\n\n";
while (loop==true)
{
char choice[10];
cout << "Please select an option:\n";
cout << "------------------------------------------------\n";
cout << "(a)Log into an account\n(b)Create an account\n(s)Search an account\n(e)Exit\n";
cout << "------------------------------------------------\n";
cout << "Choice: ";
cin >> choice;
choice[0] = tolower(choice[0]);
cout << "\n------------------------------------------------\n\n";
switch (choice[0])
{
case 'a':
display();
break;
case 's':
int n;
cout << "Enter the ID of the account: ";
cin >> n;
search(n);
break;
case 'b':
createAccount();
break;
case 'e':
loop = false;
break;
default:
system("CLS");
cout << "The option \"" << choice[0] << "\" is invalid.\n\n\n\n";
break;
}
};
cout << "\n\n\n";
cout << "Click anything to exit.";
getch();
}
Your problem is the semicolon at the end of this line:
while(fileRead.read((char *) &obj, sizeof(obj)) );
That makes this loop have an empty body. So you basically read the whole file and throw away the results, except for the last entry.
get rid of this also:
fileRead.seekg(0,ios::beg);
I don't know why you need that, it would only make you read the first entry over and over.
The other error is that you should only say 'User not found' when you've tested all the accounts and they all failed. Your loop (when you've removed the semi-colon) is saying 'User not found' after every failed test.
You probably don't find the entry you are looking for because each time you have read an entry from the file, you reset the position to the beginning. This means that your loop will run forever, reading the same entry over and over again and never finding the entry you search for.
the seek might be the problem:
while(fileRead.read((char *) &obj, sizeof(obj)) ) //;
{
// seek to start?
//fileRead.seekg(0,ios::beg);
...
}
have a look at http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html
aside, use
cout << "text" << endl;
for platform-agnostic newlines.