I am trying to create a program that ask for sales amount and displays total salary and writes the entry to a file. However my program has is only writing the last entry to the file. I have searched online for 2hours for a solution and cant find one.
I want all of the input to write to my file not just the last one
#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;
void SavingFile(); //Declartion
void Calculate();
char FileName[20];
double GrossPay;
double TotalSalary;
int employeeID=0;
char response;
int i=1;
int main()
{
SavingFile();
}
void SavingFile()
{
cout << "\nEnter the name of the file you want to create: ";
cin >> FileName;
do
{
employeeID++;
cout << endl << endl << "Enter sales amount for sales person ID " << employeeID <<" : $";
cin >> GrossPay;
Calculate();
cout <<"Sales amount for ID " << employeeID <<" : $" << TotalSalary <<endl;
cout <<endl <<endl;
do
{
ofstream Employee(FileName);
Employee <<"Employee ID: "<< employeeID <<" Sales Amount: $" << TotalSalary <<endl;
cout << endl;
i++;
}
while
(employeeID == i);
cout << "Do you want to process another employee ? (y/n): ";
cin >> response;
}
while ( (response == 'Y') || (response == 'y') );
}
void Calculate() // definition
{
TotalSalary = (GrossPay * .10) + 150;
//return TotalSalary;
}
You are overwriting the file every time you write to it.
If you want to append to the file, you need to open the file using the ios_base::app flag in addition to ios_base::out.
In your code, you must replace this:
ofstream Employee(FileName);
with this:
ofstream Employee(FileName, ios_base::out | ios_base::app);
To learn more, you can read this page on the constructor of the ofstream class. Among other things, you will find a description of the various flags you can use and what they mean.
I won't rewrite your code for you, but I'll explain the logic that you need to rewrite.
In a loop, you read a value, and call Calculate, which sets a global variable called TotalSalary. The cout probably looks ok. Try adding a cout into the while loop where you are outputting the file, and you'll see that the values aren't what they used to be.
The problem is that every time you call Calculate, you overwrite TotalSalary. You're not saving these values anywhere, but by looping through, you're assuming that the values are still there.
The solution is to write to the output file at the same time as you write to your cout. Open the ofstream at the top of main, and just output to there like you are outputting to cout.
There's no need to open the file each time in a loop, and in fact you shouldn't. (Though appending would help, if that's what you should have been doing.)
Related
Disclaimer: I am a beginner to programming, so what I say might sound really stupid
I have to make a "Telephone Directory" for school. The program isn't complete, but there are some things that I need to fix before moving on. The array TelephoneNumbers either isn't storing the numbers from the file correctly, or isn't displaying them. For the SeaerchRecords function, the first number in the file is displayed correctly, the second is displayed as "2147483647," and the rest of the numbers display as "0." The modify function also doesn't change the number, and I confirmed this with the while in the function. The string array works perfectly fine, however. May someone explain what I'm doing incorrectly?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string TelephoneNames[100];
int TelephoneNumbers[100];
void ModifyRecords(); //Function to Modify Records
void SearchRecords(); //Function to Search Records
void DeleteRecords(); //Function to Delete Records
int main()
{
fstream inputFile;
fstream outputFile;
char choice;
inputFile.open("Telephone Names.txt"); //To store
for (int count=0;count<100;count++) //file names
{ //into a
inputFile >> TelephoneNames[count]; //string
}
inputFile.close();
inputFile.open("Telephone Numbers.txt");//To store
for (int count=0;count<100;count++) //file #'s
{ //into a
inputFile >> TelephoneNumbers[count];//string
}
inputFile.close();
//Display options available
cout << " Hello, do you want to:\n";
cout << " ======================\n";
cout << "-Modify Records|Enter M\n";
cout << "-Search Records|Enter S\n";
cout << "-Delete Records|Enter D\n";
//Store choice
cin >> choice;
//Send to different function
if (choice=='M'||choice=='m')
{
ModifyRecords();
}
if (choice=='S'||choice=='s')
{
SearchRecords();
}
return 0;
}
void ModifyRecords()
{
string name;
string newname;
int newnumber;
int count=0;
cout << "Enter the name of the person: ";
cin >> name;
for (count=0;TelephoneNames[count]!=name;count++)//To determine where in the strings the new numbers need to be
{
}
cout << "Enter the new name of the person: ";
cin >> newname;
cout << "Enter the new number of the person: ";
cin >> newnumber;
TelephoneNames[count]={newname};
TelephoneNumbers[count]={newnumber};
count=0;
while (count<6)
{
cout << TelephoneNames[count] << endl;
cout << TelephoneNumbers[count] << endl;
cout << endl;
count++;
}
}
void SearchRecords()
{
string name;
int count=0;
cout << "Enter the name of the person you would like to find: ";
cin >> name;
for (count=0;TelephoneNames[count]!=name;count++)//To determine where in the strings the new numbers need to be
{
}
cout << "Name: " << TelephoneNames[count] << endl;
cout << "Number: " << TelephoneNumbers[count] << endl;
}
Since there is no any answer still and I don't see exactly the problem at this point I'll provide some suggestions how you can find a problem in your code.
In any programming situation when you can't find a bug, first task is to locate it as much precisely as you can and check all input data and assumptions. Usually, debugger is used for such purposes, but you can just output text in console before creating final version of your program.
To start with, you must check that you really received names and telephones from your file:
inputFile.open("Telephone Names.txt"); //To store
for (int count=0;count<100;count++) //file names
{ //into a
inputFile >> TelephoneNames[count]; //string
cout << TelephoneNames[count] << endl; //WE MUST SEE WHAT IS REALLY STORED IN TelephoneNames
}
inputFile.close();
inputFile.open("Telephone Numbers.txt");//To store
for (int count=0;count<100;count++) //file #'s
{ //into a
inputFile >> TelephoneNumbers[count];//string
cout << TelephoneNumbers[count] << endl; //WE MUST SEE WHAT IS REALLY STORED IN TelephoneNumbers
}
inputFile.close();
Ok, when it is checked and you are defenitely sure there is no problem in your data we can move to SeaerchRecords function doing the same procedure. We must check what is happening while you are searching:
for (count=0;TelephoneNames[count]!=name;count++)//To determine where in the strings the new numbers need to be
{
cout << "Search step: " << count << " name " << name << " found name " << TelephoneNames[count] << " number " << TelephoneNumbers[count] << endl;
}
Doing so you will locate your bug rather quickly. The problem can be in input files format, in difference of "name" and stored names format etc.
I'll provide several additional suggestion how you can improve your code.
1) Try to use const declarations for such commonly used things as number of records (const int NUMBER_OF_RECORDS = 100; insted of just putting '100' everywhere), it will reduce the amout of work and possible bugs. 2) Try to check all possible problems that you program can encounter if someting is wrong with data. What will happen if you have less than 100 records in your files now? Program crush or silent reading of unappropriate data which is even worse. Check that you haven't reach file end on any step of reading along with current check that you've reached you number of records and do something in case of unappropriate data.
3) Check the possible problems with conditions in your cycles not to run them infinite number of times. Now your condition for(count=0;TelephoneNames[count]!=name;count++)
will execute forever if there is no such name or just crush the program on count 100 or more. You should check that count doesn't exceed that value. Good luck!
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 6 years ago.
Improve this question
I'm beginning to think this is totally impossible...
I have a small console programme that is basically a small calculator, once the user has done one calculation and achieved a result the programme then loops to allow the user to do another calculation. As long as the user keeps choosing to add another calculation the programme is never ending.
Now what I would like is to be able to save ALL of the data displayed in the console to a new text file on the desktop.
I have a set of functions that declares a full file path and file name into a string, if possible I would like the programme to save the text file to this exact file path and name. If not possible then the user’s desktop will do fine.
So far I have tried Fstream but had no luck; maybe I'm doing something wrong? I'm kind of new to this all so any help would be greatly appreciated.
Below is ALL code from the programme.
#include <iostream>
#include <ctime>
#include <string>
#include <sstream>
#include <windows.h>
#include <Lmcons.h>
using namespace std;
int main()
{
//creates file name
char timeNow[20];
time_t now = time(NULL);
strftime(timeNow, 20, "%d.%m.%Y %H%Mhrs", localtime(&now));
// Creates desktop file path that includes the users user name
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
stringstream user;
string UserName;
user << username;
user >> UserName;
string pathName = "c:/users/" + UserName + "/desktop/" + timeNow + ".txt";
// Declare Variables
int suA, splitA, cornerA, streetA, sixlineA, payout;
double Cvalue = 1;
double cash;
int winnum = 0;
int table = 0;
std::string Another ("y");
// Programme Header
cout << "Roulette Bet Calculator & Payout Log!" << endl;
cout << "By Chris McCarthy" << endl << endl;
//Bet Calculator Loop
while (Another == "y") {
cout << "Table no: AR";
cin >> table;
cout << "Winning Number? ";
cin >> winnum;
char timeNow[20];
time_t now = time(NULL);
strftime(timeNow, 20, "%H:%M:%S %d/%m/%Y", localtime(&now));
cout << timeNow << endl << endl;
cout << "Please enter the chip value? " << char(156);
cin >> Cvalue;
cout << "Please enter the amount of Straight Ups? ";
cin >> suA;
cout << "Please enter the amount of Splits? ";
cin >> splitA;
cout << "Please enter the amount of Corners? ";
cin >> cornerA;
cout << "Please enter the amount of Streets? ";
cin >> streetA;
cout << "Please enter the amount of Six Lines? ";
cin >> sixlineA;
cout << endl;
// Calculates then writes the final payout and cash value
payout = (suA * 35) + (splitA * 17) + (cornerA * 8) + (streetA * 11) + (sixlineA * 5);
cash = Cvalue * payout;
cout << "The payout is: " << payout << endl;
cout << "The cash value of the payout is: " << char(156) << cash << endl << endl;
// Adds another bet or terminates programme
cout << "Add another bet? (y/n) ";
cin >> Another;
cout << "____________________________________________________________" << endl << endl;
}
return 0;
}
In C++98 Formation of ofstream open() is:
void open (const char* filename, ios_base::openmode mode = ios_base::out);
Your pathName is string type. Copying the pathName value in char array and passing it in open() method worked in my pc.
So what I did (!!!), declared a char array and copied pathName into that array and use it in open().
char pname[100] = {'\0'};
for(int i=0; i<sizeof(pname); i++) {
pname[i] = pathName[i];
}
std::ofstream ofs;
ofs.open (pname, std::ofstream::out | std::ofstream::app);
and right after each cout << ... << endl; I put ofs << ...<< endl;
which generated a file in my desktop named "27.04.2016 1643hrs.txt" and I got these string inside the file:
Roulette Bet Calculator & Payout Log!
By Chris McCarthy
Table no: ARWinning Number? 16:43:19 27/04/2016
Please enter the chip value? œPlease enter the amount of Straight Ups? Please enter the amount of Splits? Please enter the amount of Corners? Please enter the amount of Streets? Please enter the amount of Six Lines?
The payout is: 238
The cash value of the payout is: œ238
Add another bet? (y/n) ____________________________________________________________
Don't forget to include "#include <fstream>" in header
Use ofstream, ofstream consoleCopy; consoloeCopy.open(filepath); where filepath is the path you generate with your functions. Then it's just a matter of writing to the file, consoleCopy << consoleString;.
To achieve what you want, though, you're going to need to either store all of the output/input into a string and write it to the file at the end, or write to the file as you go. The following site should help you with writing to files, http://www.cplusplus.com/doc/tutorial/files/
I've been scanning through stackoverflow but I'm not finding any previous posts on my situation.
My program I want to write is just something to keep track of daily tips, hours worked, and number of days worked. So far it prints and creates a tips.txt file, but for some reason every time I run the program to input additional numbers it clears the previous entries . Still a lot of work that needs to be done, but I want to fix this problem first. Any ideas?
#include <fstream>
#include <iostream>
using namespace std;
int daysWorked(int); // Caculates the number of days worked
int hoursWorked(int); // Caculates hours worked
double profit(double); // Caculates the profit year to date
int main()
{
double tip;
int hours;
int month, day;
ofstream readFile;
cout << " Enter the month and then the day, followed by hours worked, followed by money made" << endl;
if (!"tips.txt") // checks to see if tips.txt exists
{
ofstream readFile("tips.txt"); // if tips.txt doesn't exists creates a .txt
}
else
readFile.open("tips.txt" , std::ios::app && std::ios::in && std::ios::out); // if tips.txt exits just opens it?
if (cin >> month >> day >> hours >> tip) // reads in the user input
{
cout << endl;
readFile << " Date :" << month << "/" << day << " " << "Hours:" << hours << " " << "Money made: " << tip << endl; // prints out the user input
cout << endl;
readFile.close();
}
return 0;
}
Remove the following code:
// As rpattiso stated, this does not test for the existence of a file
//if (!"tips.txt") // checks to see if tips.txt exists
//{
// ofstream readFile("tips.txt"); // if tips.txt doesn't exists creates a .txt
//}
//else
This alone should be sufficient:
// This will create the file if it doesn't exist and open existing files for appending (so you don't need to test if the file exists)
ofstream readFile.open("tips.txt" , std::ios::app); // open for writing in append mode
I'm new to C++. I decided to not watch the next tutorial and put my skills to use, by making a funny Mind Reader application. I'm pleased with myself, however, even though I've ironed out most bugs, I still have one concerning the exit function. I read the C++ documentation for it, and I'm not sure what I did wrong. I did exit(0);. I have a very weird error, which is:
no match for call to '(std::string {aka std::basic_string<char>}) (int)
I have searched online, however I am still unaware of what the problem is. My error is on line 59 (marked in the code):
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
//declaring variables to be used later
string name;
string country;
int age;
//header goes below
cout << "#######################################";
" ############ MIND READER ############"
"#######################################\n\n";
//asks if the user would like to continue and in not, terminates
cout << "Would like you to have your mind read? Enter y for yes and n for no." << endl;
cout << "If you do not choose to proceed, this program will terminate." << endl;
string exitOrNot;
//receives user's input
cin >> exitOrNot;
//deals with input if it is 'y'
if (exitOrNot == "y"){
cout << "Okay, first you will need to sync your mind with this program. You will have to answer the following questions to synchronise.\n\n";
//asks questions
cout << "Firstly, please enter your full name, with correct capitalisation:\n\n";
cin >> name;
cout << "Now please enter the country you are in at the moment:\n\n";
cin >> country;
cout << "This will be the final question; please provide your age:\n\n";
cin >> age;
//asks the user to start the sync
cout << "There is enough information to start synchronisation. Enter p to start the sync...\n\n";
string proceed;
cin >> proceed;
//checks to see if to proceed and does so
if (proceed == "p"){
//provides results of mind read
cout << "Sync complete." << endl;
cout << "Your mind has been synced and read.\n\n";
cout << "However, due to too much interference, only limited data was aquired from your mind." << endl;
cout << "Here is what was read from your mind:\n\n";
//puts variables in sentence
cout << "Your name is " << name << " and you are " << age << " years old. You are based in " << country << "." << endl << "\n\n";
cout << "Thanks for using Mind Reader, have a nice day. Enter e to exit." << endl;
//terminates the program the program
string exit;
cin >> exit;
if (exit == "e"){
exit(0); // <------------- LINE 59
}
}
}
//terminates the program if the input is 'n'
if (exitOrNot == "n"){
exit(0);
}
return 0;
}
Thanks
The local variable exit shadows other identifiers from outer scopes with the same name.
To illustrate with a smaller example:
int main()
{
int i;
{
int i;
i = 0; // assign to the "nearest" i
// the other i cannot be reached from this scope
}
}
Since the only exit visible is an object of type std::string, the compiler sees exit(0) as a call to operator()(int) and throws a hissy fit when it doesn't find one among std::string members.
You can either qualify the name (std::exit(0);) or rename the variable. And since all of your code is in main you can simply say return 0; instead.
Try using return 0; or return EXIT_SUCCESS;. It's the exact same thing. Also, you can only input one word into a cin. Instead, use getline(cin, string name); If it still doesn't work, add a cin.ignore(); before your getline(cin, string name);, like this:
//stuff
string country;
cout << "Now please enter the country you are in at the moment:\n\n";
cin.ignore();
getline(cin, country);
//stuff
return 0;
The problem is arrising because you declared a standard keyword as the name of a local variable.
Now as the local variable is of type sting it is not able to take it as its value.
I'm writing a file matching program for a project for school. The idea is that one program allows you to enter info as follows: 1000 (acct number) Jane Doe 54.50 (balance). Then allow you to enter the account number and a transaction amount for the second program to combine and update a new master file.
The programs are working together just fine (the second one takes information from the first, including any transactions and updates the new balance - searching by account number) but the problem I am running into is with the name.
---Wasn't clear here. When I ask for a name and I put in a single string of characters, the program works fine, if I try to put in a full name, like Jane Doe I go into the loop mentioned below.
I've tried char name[20] which puts me into an infinite loop and I have to 'x' out of the program and I've tried assigning first and lastName to string. That worked for the writing but the program that takes the input file oldMaster and the transaction file inTransaction then outputs a new file newMaster, doesn't recognize the name.
I've tried getline also which isn't working for me, probably programmer error.
Should this be done as an array, if that's possible for this? I think I'm getting hung up on the fact that I am editing files. Answers are fine - but I like to figure it out on my own, just looking for a little guidance on where to go from here.
Hopefully this was fairly clear - if not I'll be happy to explain again in a different way. Just frustrated that I'm this close and can't solve it.
Thanks in advance!
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iomanip>
using namespace std;
void createOldMaster()
{
ofstream oldMaster;
int accountNum;
double balance;
char name[15];
oldMaster.open("oldmast.dat", ios::out);
if(!oldMaster)
{
cout << "Unable to open the file." << endl;
exit(1);
} // end if
cout << "Enter the account number (0 to exit)." << endl;
while(true)
{
cout << "Account Number: ";
cin >> accountNum;
if(accountNum == 0)
break;
else
{
\\ This is where it hangs up if I use a first and last name
cout << "\nName: ";
cin >> name;
cout << "\nBalance : " << endl;
cin >> balance;
oldMaster << accountNum << " " << name << " " << balance << endl;
}
}
} //end createOldMaster
void createTransaction()
{
ofstream inTransaction;
int accountNum;
double balance;
inTransaction.open("trans.dat");
if(!inTransaction)
{
cout << "Unable to open the transaction file." << endl;
exit(1);
}
cout << "Enter the account number and balance (0 to exit): " << endl;
while(true)
{
cout << "Account Number: " << endl;
cin >> accountNum;
if(accountNum == 0)
break;
else
{
cout << "Balance: " << endl;
cin >> balance;
inTransaction << accountNum << " " << balance << endl;
}
}
} //end createTransaction
int main()
{
createOldMaster();
createTransaction();
return 0;
}
Your best bet is to use as much of the standard C++ library as you can. Have a reference handy, maybe even a copy of the C++ standard if you're so inclined, and look for shortcuts to make your work easier and your code shorter.
Avoid primitive arrays and primitive strings wherever possible. Instead of primitive arrays try to use std::vector. Instead of primitive strings try to use std::string. Instead of C's FILE* try to use std::ofstream and std::ifstream. If you need to prohibit two accounts with the same account number then choose a C++ container that guarantees unique elements. If you need to find an element in a container try to use a member function of the container for the search, and if that doesn't exist then a standard search function from the standard C++ algorithms.
Reuse and steal mercilessly.