C++ fstream building but not running - c++

I'm building a program for my class the requires us to import data from a .txt file and the item names/ prices will be used to calculate saltes tax and grand total. My teacher put this up as an example, but I can't get it to run.
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
int main()
{ // Beginning of main function
string name;
ifstream data_in;
ofstream data_out;
int cnt=0;
int number;
struct Item
{
int item_n;
char disc[50];
float price;
};
Item store[999];
data_in.open("cost.txt");
data_out.open("file_out.txt");
while(!data_in.eof())
{
//cout << "Enter in the item number: ";
data_in >> store[cnt].item_n;
//cout << "Enter in the description for item number " << store[cnt].item_n << ": ";
data_in >> store[cnt].disc;
//cout << "Enter in the price for the " << store[cnt].disc << ": $";
data_in >> store[cnt].price;
cnt++;
}
cout << endl << endl;
number = cnt;
for (cnt=0; cnt<number; cnt++)
{
name = store[cnt].disc;
cout << setw(5) << store[cnt].item_n << " " << store[cnt].disc << setw(16-name.length()) << "$" << setw(9) << store[cnt].price << endl;
}
for (cnt=0; cnt<number; cnt++)
{
name = store[cnt].disc;
data_out << setw(5) << store[cnt].item_n << " " << store[cnt].disc << setw(16-name.length()) << "$" << setw(9) << store[cnt].price << endl;
}
return 0;
}
And this is the information in the cost.txt file
Books 45.01
Pens 21.03
Pencils 10.90
Hats 50.00
Caps 800.00
Food 1.00

The code you've written reads three things for each Item: the item number, the description, and price.
The sample data file you shown contains only two things for each item: what looks to be a description, and a price.
The expected data format does not match the contents of the input file. This code will never work, as is. One or the other is wrong. Plus all the other problems with the code, as mentioned in the comments.

Try the following changes, the rest of your code seems to work:
data_in.open("cost.txt");
data_out.open("file_out.txt");
if (!data_in.is_open() || !data_out.is_open()) //Test if files opened correctly...
{
cout << "Failed to open a file!\n";
return 1;
}
float SalesTotal = 0;
while(true)
{
if (!(data_in >> store[cnt].disc))
{
//Failed to read first element in this record - could be eof or format error
if (data_in.eof())
break; //eof - all records read.
cout << "Format error first field\n";
return 1; //format error on first field.
}
if (!(data_in >> store[cnt].price))
{
cout << "Format error second field\n";
return 2; //format error on second field.
}
store[cnt].item_n = cnt + 1; //Item number is not a field in your file, use the counter...
SalesTotal += store[cnt].price;
cnt++;
}
if (!cnt)
{
cout << "No records read\n";
return 3; //No valid records read.
}
float GrandTotal = ((SalesTotal / 100) * 6) + SalesTotal;
cout << "Sales total: " << SalesTotal << " Grand total:" << GrandTotal << "\n";

Related

How to rename and remove txt file in c++ using remove() to update the contents?

I have these 2 files and I need to update the file by updating into the temp file. I did it but how do I rename the temp file to the old file and then delete the old file?
ifstream in_file;
ofstream temp_file;
char in_file_name[] = "input practical 12 part d.txt";
char temp_file_name[] = "temp.txt";
I tried to do like this and the file name don't change. I need some explanation on this and how it works. This is the site I referred to and I don't understand it.
https://www.programiz.com/cpp-programming/library-function/cstdio/rename
in_file.close();
temp_file.close();
int rename(char *temp_file_name, char *in_file_name);
Also, can I update the file by renaming the temp file to the old file and then rename the old file to temp file so that the user don't need to recreate a temp file to update the contents in the file?
Here's the whole code just in case
Write and test a program that reads product details from a file and stores the information in an array of
structures. The program then prints a menu to allow the user to do any of the following:
List all products
Search the price of a product
Update the price of a product
Exit
If the user chooses to exit, the program will write the updated data in the array of structures to the file.
The product information includes product number, description and price.
Note: You may assume that the total number of product details read from the file will not exceed 30, the product
number consist of 6 numbers, and the product description will not exceed 30 characters.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
typedef struct
{
char product_num[5];
char product_des[29];
float price;
}PRODUCT_TYPE;
int main()
{
ifstream in_file;
ofstream temp_file;
char in_file_name[] = "input practical 12 part d.txt";
char temp_file_name[] = "temp.txt";
in_file.open(in_file_name);
temp_file.open(temp_file_name);
if (!in_file || !temp_file)
{
if (!in_file)
{
cout << "Error opening input file" << endl;
}
else if (!temp_file)
{
cout << "Error opening output file" << endl;
}
}
else
{
PRODUCT_TYPE product[50];
int index = -1;
int choice;
string line;
in_file >> product[++index].product_num;
cout << "Succesful run" << endl;
cout << "Menu (Type number for the function)" << endl;
cout << "1. List all products\n2.Search the price of a product\n3.Update the price of a product\n4.Exit\n";
cin >> choice;
if (choice == 1)
{
cout << setw(18) << left << "Product Index" << setw(35) << left << "Product Description" << "Price" << endl;
}
else if (choice == 4)
{
cout << setw(18) << left << "Product Index" << setw(35) << left << "Product Description" << "Price" << endl;
}
while (in_file)
{
in_file >> product[index].product_des >> product[index].price;
if (choice == 1)
{
cout << setw(18) << left << product[index].product_num << setw(35) << left << product[index].product_des << product[index].price << endl;
}
else if (choice == 2)
{
cout << "Type the product number to get the price" << endl;
cout << "Product Number: ";
cin >> product[index].product_num;
cout << "Price: ";
cout << product[index].price << endl;
}
else if (choice == 3)
{
float new_price;
cout << "Enter the product number to change its price: ";
cin >> product[index].product_num;
cout << "Enter the updated price list: ";
cin >> new_price;
if (new_price != product[index].price)
{
temp_file << " " << product[index].product_num << " "<< product[index].product_des << " "<< new_price << endl;
}
}
else if (choice == 4)
{
cout << setw(18) << left << product[index].product_num << setw(35) << left << product[index].product_des << product[index].price << endl;
}
in_file >> product[++index].product_num;
}
in_file.close();
temp_file.close();
int rename(char *temp_file_name, char *in_file_name);
}
return 0;
}
Thanks.
What this is telling you:
int rename(char *temp_file_name, char *in_file_name);
is that there's a method called rename that takes two arguments. You've defined your two file names like this:
char in_file_name[] = "input practical 12 part d.txt";
char temp_file_name[] = "temp.txt";
So I believe you've written temp.txt, and now you want to move it into place over the other one with the really obnoxious name.
rename(temp_file_name, in_file_name);
Beware: this destroys the original input file, so if you want to save it:
rename(in_file_name, "copy_of_input.txt");
Does that make sense?

Program cannot run due to no operator "<<" matches these operands

I get an error of "no operator matches these operands" when using the part of the code outputFile << customerName << "your Monthly payments are " << monthlyPay << endl;. Overall, I need the code to Add the ability to save data to disk in one or more files and a menu should give the user the option to save or retrieve data. I have not gotten past the error to properly run the program. Can you please help fix error.
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <vector>
#include<fstream>
using namespace std;
void menu(void);
void writeData(void);
void readData(void);
const char FileName[] = "CourseProjectAvilaF.txt";
//Variables
vector <double> Loanlgth, Loanamt, interestRate, totalInterest;
vector <double> monthlyPay(100), loanTotal(100), creditScore(100);
vector <string> customerName;
int main()
{
menu();
return 0;
}
void menu(void)
{
const int INPUT_CUSTOMER = 1, DISPLAY_LOAN = 2, EXIT_PROGRAM = 3;
int option;
//Program
cout << "Thank you for choosing The Bank of UA for your loan requirements!\n\n";
do
{
cout << "UA Bank menu:\n\n"
<< "1. Enter your information\n"
<< "2. See your loan requirements\n"
<< "3. Exit program\n\n"
<< "Choose an option: ";
cin >> option;
while (option < INPUT_CUSTOMER || option > EXIT_PROGRAM)
{
cout << "Please enter a valid menu option: ";
cin >> option;
}
if (option == 1)
{
writeData();
}
if (option == 2)
{
readData();
}
} while (option != EXIT_PROGRAM);
}
//function to read customer information
void writeData(void)
{
fstream outputFile;
outputFile.open(FileName, fstream::app);
int index;
int numCustomers = 0;
cout << "Please enter the number of customers you would like\n"
<< " to enter loan information for: ";
cin >> numCustomers;
for (index = 0; index < numCustomers; index++)
{
string tempName;
double tempLoanamt, tempLoanlgth, tempcreditScore, tempinterestRate,
tempinterest;
cout << "Please enter your name: ";
cin >> tempName;
customerName.push_back(tempName);
cout << "Please enter the loan amount: $";
cin >> tempLoanamt;
Loanamt.push_back(tempLoanamt);
cout << "Please enter the length of the loan in months: ";
cin >> tempLoanlgth;
Loanlgth.push_back(tempLoanlgth);
cout << "What is your current credit score? ";
cin >> tempcreditScore;
creditScore.push_back(tempcreditScore);
//This will determine interest rate and overall loan amount when calculated
if (tempcreditScore <= 650)
tempinterestRate = .12;
else
tempinterestRate = .05;
interestRate.push_back(tempinterestRate);
//Calculations
tempinterest = Loanamt[index] * interestRate[index];
totalInterest.push_back(tempinterest);
loanTotal[index] = (Loanamt[index] + totalInterest[index]);
monthlyPay[index] = loanTotal[index] / Loanlgth[index];
// Out put files to write data to be saved
outputFile << customerName << "your Monthly payments are " << monthlyPay << endl;
outputFile << "Your total interest is " << totalInterest << endl;
outputFile << "You owe " << loanTotal << endl;
outputFile << "You have " << Loanlgth << " months to pay off your balance" << endl;
}
outputFile.close(); //Close file
}
//function loan information
void readData(void)
{
int index;
int numCustomers = 0;
ifstream inputFile;
inputFile.open(FileName, fstream::in);//Open the file with read mode
//Display monthly payment
cout << fixed << setprecision(2);
for (index = 0; index < numCustomers; index++)
{
cout << customerName[index] << " your total loan is " << loanTotal[index]
<< "\n"
<< "with a monthly payment of $" << monthlyPay[index] << "\n"
<< "for " << Loanlgth[index] << " months with an interest\n"
<< "rate of " << interestRate[index] << endl;
}
}
It's simple enough, you got it right everywhere else in your program.
When you want to access a particular element of a vector you use an index. Like this
outputFile << customerName[index] << "your Monthly payments are " << monthlyPay[index] << endl;
outputFile << "Your total interest is " << totalInterest[index] << endl;
outputFile << "You owe " << loanTotal[index] << endl;
outputFile << "You have " << Loanlgth[index] << " months to pay off your balance" << endl;
customerName and monthlyPay are vectors. You can't stream them directly. Instead you can do something like
for (auto const &name : customerName)
outputFile << name;

Binary Search Output Issue in Inventory Program c++

I am having issues with binary search function within my homework (I am completely done with it except for this one issue).
The program allows a user to manage the inventory of a small store that sells various products of any type. It will first read the inventory from a text file named “inventory.dat”, reading the product name, sku, quantity, and price. It will contain up to 100 products.
Then, it should offer the user a menu with the following options:
Display the inventory sorted by sku. (displayInventory function)
Lookup a product by sku. (lookupSku function)
Lookup a product by name. (lookupname function)
Quit
The program should perform the selected operation and then re-display the menu.
When I select option 2 and enter a sku number, my program outputs a random item's information instead of the one that was typed in by the user.
Here is my code starting in the main function along with the lookupBySku function:
int main()
{
// Initialize variables & array
int userInput;
//max array size
const int MAX_SIZE = 100; //const to make it constantly be 100
//declare and open input file
ifstream fin;
fin.open("inventory.dat");
//declare strings to hold data
string productName, sku, quantity, price;
if (!fin) // checking if file was inputted correctly or not.
{
cout << "File not found! Try again. " << endl;
return 1;
}
Inventory items[MAX_SIZE];
Inventory temp[MAX_SIZE];
cout << left << setw(20) << "Product Name " <<
left << setw(10) << "sku #" <<
left << setw(3) << "Quantity " <<
left << setw(0) << " Price\n";
//declare number of objects in inventory
int numOfObjects = 0;
while(!fin.eof())
{
getline(fin, productName);
getline(fin, sku);
getline(fin, quantity);
getline(fin, price);
if(productName == "")
{
break;
}
items[numOfObjects].name = productName;
cout << left << setw(20) << items[numOfObjects].name;
items[numOfObjects].sku = sku;
cout << left << setw(10) << items[numOfObjects].sku;
items[numOfObjects].quantity = quantity;
cout << left << setw(4) << items[numOfObjects].quantity;
items[numOfObjects].price = price;
cout << left << setw(0) <<"\t\t" << items[numOfObjects].price << endl;
++numOfObjects;
}
//check to see if there are more than 100 items
if(numOfObjects > 100)
{
cout << "File is too large, terminating program...\n";
return -1;
}
// Constants for menu choices
const int DISPLAY_BY_SKU = 1,
LOOKUP_BY_SKU = 2,
LOOKUP_BY_NAME = 3,
QUIT_CHOICE = 4;
do
{
// Set up numeric output formatting.
cout << fixed << showpoint << setprecision(2);
cout << "Manage Inventory Menu\n" <<endl;
cout << "1. Display inventory sorted by sku. " <<
"\n2. Lookup a product by sku. " <<
"\n3. Lookup a product by name. " <<
"\n4. Quit the program\n" << endl;
cout << "Enter your choice : ";
cin >> userInput;
cout << endl;
while (userInput < DISPLAY_BY_SKU || userInput > QUIT_CHOICE)
{
cout << "Please enter a valid menu choice: ";
cin >> userInput;
}
switch(userInput)
{
case DISPLAY_BY_SKU:
{
displayInventory(items, numOfObjects);
break;
}
case LOOKUP_BY_SKU:
{
lookupSku(items, numOfObjects);
break;
}
case LOOKUP_BY_NAME:
{
lookupName(items, numOfObjects);
break;
}
case 4:
cout << "Exiting the program." <<endl;
break;
}
}
while (userInput != QUIT_CHOICE);
fin.close();
return 0; }
void lookupSku (Inventory items[], int numOfObjects) {
string number;
int first = 0;
int last = numOfObjects - 1;
int middle;
int position = -1;
bool found = false;
cout << "Enter the sku that you'd like to search for : ";
cin >> number;
cout << endl;
while(!found && first <= last)
{
middle = (first + last)/2;
if(items[middle].sku == number)
{
found = true;
position = middle;
}
else if(items[middle].sku > number)
{
last = middle - 1;
}
else if(items[middle].sku < number)
{
first = middle + 1;
}
}
cout << "Your item is shown below : \n" << endl
<< "Product Name : "<< items[middle].name << endl
<< " Sku : " << items[middle].sku << endl
<<" Quantity : " << items[middle].quantity << endl
<< " Price : " << items[middle].price << endl
<< endl;
}

Why does program complain of too many commas?

Here is my code, I have attached the screenshot of what output Zybooks expects, and what my output is. I am trying to get it to output exactly what Zybooks is asking, however something seams to be wrong. It is compiling though. Or maybe Zybooks is just being stupid?
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <cstring>
using namespace std;
int main() {
string title;
string col1;
string col2;
string val;
int numCommas = 0;
vector<string> stringData;
vector<int> intData;
cout << "Enter a title for the data:" << endl;
getline(cin, title);
cout << "You entered: " << title << endl << endl;
cout << "Enter the column 1 header:" << endl;
getline(cin, col1);
cout << "You entered: " << col1 << endl << endl;
cout << "Enter the column 2 header:" << endl;
getline(cin, col2);
cout << "You entered: " << col2 << endl << endl;
while (1) {
cout << "Enter a data point (-1 to stop input):" << endl;
getline(cin, val);
if (val == "-1") {
break;
}
if (val.find(',') == -1) {
cout << "Error: No comma in string." << endl << endl;
}
else {
for (int i = 0; i < val.length(); i++) {
if (val.at(i) == ',') {
numCommas++;
if (numCommas > 1){
break;
}
}
}
if (numCommas == 1) {
stringData.push_back(val.substr(0, val.find(',')));
intData.push_back(stoi(val.substr(val.find(',') + 1, val.length() - 1)));
cout << "Data string: " << val.substr(0, val.find(',')) << endl;
cout << "Data integer: " << stoi(val.substr(val.find(',') + 1, val.length() - 1)) << endl;
}
else {
cout << "Error: Too many commas in input." << endl << endl;
}
}
}
return 0;
}
Thanks.
Thanks.
Your problem is that you initialise numCommas to zero at the start of the program rather than at the start of each author input. That means, once it exceeds one, it will stay that high at least(a), meaning future inputs will always be seen as having too many commas.
You just need to set it to zero immediately before checking each input.
(a) Well, until it wraps around (if it wraps around). But that will be an awful lot of commas you need to input :-)

Creating Table headers?

OK, in this program I am required to make a table based of user input. The problem is I cannot figure out how to get the table headers to properly align with the information that is displayed. The table headers would not line up from lets say if the user enters in Michael for player one and Michael Jordan for player 2. Any advice to allow the headers to properly align with the displayed input regardless of character length would be greatly appreciated, thanks.
Here is my code:
#include <iostream>
#include <string>
#include <iomanip>
#include <cstdlib>
using namespace std;
//struct of Basketball Player info
struct BasketballPlayerInfo
{
string name; //player name
int playerNum, //player number
pointsScored; //points scored
};
int main()
{
int index, //loop count
total = 0; //hold total points
const int numPlayers = 5; //nuymber of players
BasketballPlayerInfo players[numPlayers]; //Array of players
//ask user for Basketball Player Info
cout << "Enter the name, number, and points scored for each of the 5 players.\n";
for (index = 0; index < numPlayers; index++)
{
//collect player name
cout << " " << endl;
cout << "Enter the name of player # " << (index + 1);
cout << ": ";
//input validation
if(!(getline(cin, players[index].name)))
{
cout << "Player Name must be alphabetical characters only!\n";
cout << "Program terminating please start over." << endl;
system("pause");
exit(0);
}
//getline(cin, players[index].name);
//collect players number
cout << "Enter the number of player # " << (index + 1);
cout << ": ";
//input validation
if(!(cin >> players[index].playerNum))
{
cout << "Player Name must be numeric characters only!\n";
cout << "Program terminating please start over." << endl;
system("pause");
exit(0);
}
//collect points scored
cout << "Enter points scored for player # " << (index + 1);
cout << ": ";
//input validation
if(!(cin >> players[index].pointsScored))
{
cout << "Player Name must be numeric characters only!\n";
cout << "Program terminating please start over." << endl;
system("pause");
exit(0);
}
cin.ignore();
}
//display
cout << "\n";
cout << "Here is the information for each player: \n";
cout << fixed << showpoint << setprecision(2);
cout << "\n";
cout << " \tName\tNumber\tPoints\n";
cout << "------------------------------------------------" << endl;
for(index = 0; index < numPlayers; index++)
{
cout << "Player # " << (index + 1);
cout << ": \t" << players[index].name << "\t" << players[index].playerNum << "\t" << players[index].pointsScored << endl;
cout << "------------------------------------------------" << endl;
}
//display total points scored by all players
for(index = 0; index < numPlayers; index++)
{
//hold total
total += players[index].pointsScored;
}
cout << "Total Points scored are: " << total << endl;
system("pause");
return 0;
}
you could use setw io manipulator which comes under #include <iomanip>.
cout << setw(20) << "Column1"
<< setw(20) << "Column2"
<< setw(8) << "Column3";
or you could use Boost library
// using Boost.Format
cout << format("%-20s %-20s %-8s\n") % "Column1" % "Column2" % "Column3";
Take a look at the setw and setfill functions. You can use them to assign a minimum width to your columns, which will make for much cleaner output formatting than tabs.