Hello Deadweight77,
I do not know if this is homework or something else. It would help to know if you are stuck with the input files or if you could change them?
zapshe has made some very good points that need addressed.
For the input file another option would be:
John Doe,115
Jane Doe,145
Travis Scott,76
William Smith,246.75
Patrick Michaels,89.54
Courtney Desmond,127.32
|
This way you could read the file with:
1 2 3
|
std::getline(inFile, name, ',');
inFile >> balance;
inFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
|
Since I mentioned it early, your use if
std::cin.ignore();
is not the best way to use this. Without any parameters the statement will ignore the defaults of one character or the new line (\n) whichever comes first. The problem is should the input buffer have more than one character in it the anything after the first character will be left in the input buffer. That could be a problem especially if followed by a "getline".
Using
inFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
or the above "inFile" will clear more than one character from the input buffer. The first parameter of "ignore" is just a large number. Some people use "1000" or "10000" and this should work most of the time. To be sure that the entire input buffer is cleared
std::numeric_limits<std::streamsize>::max()
will return the largest possible number available for the computer, operating system and header files that are being used. This is because different computers will have different set ups and a different size for the input buffer. This just makes sure that you are getting the largest possible number and is the most often used and suggested.
.ignore
works on a stream. This could either be either "std::cin" or a file stream.
Before I could get the code to run I had to fix a two small errors. When I tried to compile your original code I received three warnings, but no errors.
In the function "deposit" "total_money" is defined as a "float", but "money_deposit" is defined as a "double". Converting from a "double" to a "float" could cause loss of data as a "float" is smaller than a "double", (in simple terms). You are better to use "double" for the floating point type.
Also the variable "start_money" is defined, but never used.
When the program ran I noticed that the if statements in "main" are a problem. Being separate if statements each one is checked even if it does not need to be. "if/else if" statements would work better or maybe even a switch.
The problem came at
if (anwser2 == '1')
. BTW the proper spelling is "an
swer". Your "s" and "w" are reversed. When the program ran it stopped here telling that "answer2" is an uninitialized variable. And it has never received a value before it is used.
Another thing I noticed is that you are passing variables to functions by reference, but some of these variables are never used by the function. Most of these variables should be defined in the function and returned if needed.
The function "display", or what should be "mainMenu" returns an "int" but is never used in "main". You are also passing a variable by reference and that could be a problem.
As I was working on the "mainMenu" I realized that you are presenting numbers for your choices, but taking in this number as a "char". The number "1" and the character "1" are two different values. "1" has the ascii value of one, but the character "1" has the ascii value of "49". This is not a big problem, but it does not work to your advantage.
This is something I was working with for the main menu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
int display() // <--- Would be better as "mainMenu".
{
constexpr size_t WIDTH{ 50 };
int choice{};
//std::string spaces(WIDTH, ' '); // <--- An alternative.
do
{
CLS;
std::cout << "\n\n";
std::cout << std::setw(WIDTH) << ' ' << "=================" << '\n';
std::cout << std::setw(WIDTH) << ' ' << "Banking Managment" << '\n';
std::cout << std::setw(WIDTH) << ' ' << "=================" << '\n';
std::cout << std::setw(WIDTH) << ' ' << "1. New account" << '\n';
std::cout << std::setw(WIDTH) << ' ' << "2. Existing account" << '\n';
std::cout << std::setw(WIDTH) << ' ' << "4. Exit" << '\n';
//std::cout << spaces << "Test" << std::endl; // <--- An alternative.
std::cout << std::setw(WIDTH) << ' ' << "Enter choice: ";
std::cin >> choice;
if (!std::cin)
{
std::cout << "\n"<<std::setw(WIDTH)<< ' ' << "Invalid choice! Please use numbers: ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
std::this_thread::sleep_for(std::chrono::seconds(3)); // Requires header files "chrono" and "thread".
}
else if (choice < 1 || choice > 4)
{
std::cout << "\n" << std::setw(WIDTH) << ' ' << "Invalid Choice! Numbers are 1 - 4: ";
std::this_thread::sleep_for(std::chrono::seconds(3)); // Requires header files "chrono" and "thread".
}
} while (choice < 1 || choice > 4);
return choice;
}
|
I defined "spaces" as a way to show you an alternative to using "std::setw". The part the should look different to you (
std::setw(WIDTH) << ' '
) defines a block the size of "WIDTH" and prints one space padding the rest of the block with spaces. This work better to position the menu.
By defining "choice" as an "int" this uses the if statement to catch anything that is not a number. I found the the "else if" worked the best for checking the range of the input.
I have found that doing a menu function this way or something similar works the best to get the input and validate it and at the end only return a valid input to use.
The concept may be ahead of where you are, but worth taking the time to understand.
In the N_accounts" function all you need is:
1 2
|
std::ofstream outfile;
outfile.open("Accounts.txt", std::ios::app);
|
Notice: since you defined the file stream as an "ofstream" the default in the open statement is for output. You do not need to tell to open for "output", but you do need to tell it to append the file. Otherwise it would clear the contents and then use the defaults of "out" and "app".
Just so you know this can be shortened to just:
std::ofstream outfile("Accounts.txt", std::ios::app);
. This not only defines the file stream, but opens the file for append. Either way works.
In the if statement you use "std::toupper()". You should also include the header file <cctype>.
Do not count on this header file being included for you. I can tell you are using a Windows computer, but I do not know what IDE you are using. The short answer is that not all operating systems, IDEs and compilers are the same. On another system <cctype> may not be included with the header file <iostream>.
Backing up a bit I agree with what
zapshe
is saying. A struct stored in a vector or an array work much better than reading the file every time you need to. It is quicker to work through the vector than to read the file. And the vector can grow as you need it holding only what you need and having no wasted space as an array does.
I have only worked with the first three functions so far. I will start looking into the rest and see what I can come up with.
Hope that helps,
Andy