Replace white space with another character after calling function c++ - c++

I need help getting declared string function to change white space of input file to a specific character.
if (infile.fail())
{
cout << "The file doesn't exist";
exit(-1);
}
else
{
numBooks = readFile (infile, magSub, 260);
for (i=0; i<numBooks; i++)
{
cout << "Last Name: " << magSub[i].lastName << endl;
cout << "First Name: " << magSub[i].firstName << endl;
cout << "Street Address: " << magSub[i].address << endl;
cout << "City: " << magSub[i].city << endl;
cout << "State or Province: " << magSub[i].state << endl;
cout << "Country: " << magSub[i].country << endl << endl;
cout << "Zip or Postal Code: " << magSub[i].zip << endl;
cout << "Expiration Date: " << magSub[i].expDate << endl;
cout << "Subscriber Number: " << magSub[i].subNum << endl << endl;
}
writeFile(outfile, magSub, numBooks);
}
}
void fillSpace (string &expDate)
{
for (int i=0; expDate.length(); i++)
{
if (isspace(expDate[i]))
expDate[i] = '0';
}
}
I have the function declared above main. I know I need to call the function but I can't get it to change the white spaces.

In your code for fillSpace, you are not checking for the end of string condition. You should use i<expDate.length() for checking the end of string.

You have missed the check condition in for loop of fillSpace function.
for (int i=0; i < expDate.length(); i++)
And for calling the function
you have to declare a string which will store the string from the magSub[i].expDate.
and then pass that string to the function fillSpace.
After that you will get the string with replaced char space with '0'.
cout << "Expiration Date: " << magSub[i].expDate << endl;
please use the following code:
string temp = magSub[i].expDate; // copy the string to the temp string/char array
fillSpace (temp); // Missing Line for function call
cout << "Expiration Date: " << temp << endl; // replace line with
Hope
this will Help you.

Related

How to edit the specific line in a text file?

How should I edit the specific line in a text file? And how should I avoid overwriting issue. ( How do I keep the record I had added before instead of replacing them by the new records?)
I tried to use line.replace but it says " No matching member function for call to replace ".
else if(choice == 4){
// count++;
string edit;
string newdate;
double newincome;
double newoutcome;
double EditTodayBalance = 0;
string emptySpace = " ";
// string sentence;
cout << " There are " << count << " record(s) in the file " << endl;
cout << " Please enter the date to edit " << endl;
cin >> edit;
size_t pos;
ifstream Record("BankRecord.txt");
if (Record.is_open()) {
while (getline(Record, line)) {
pos = line.find(edit);
if (pos != string::npos) // string::npos is returned if
string is not found
{
cout << line << endl;
cout << " Enter what you want to replace " << endl;
cout << " Please enter the new date you want to put " << endl;
cin >> newdate;
cout << " Please enter the new income you want to put " << endl;
cin >> newincome;
cout << " Please enter the new outcome you want to put " << endl;
cin >> newoutcome;
cout << " Your new Record is " << endl;
cout << count << emptySpace << newdate << emptySpace << newincome << emptySpace << newoutcome << endl;
//line.replace()
}
}
}
EditTodayBalance = newincome - newoutcome;
cout << " Today's balance is " << EditTodayBalance << endl;
cout << " Please reenter your choice " << endl;
cin >> choice;
}
I expect if the old line is " 1 2/2/2019 32 21 " and I input the new line to be " 1 2/3/2019 22 11 ". Then when I open the file the record will be the new one.
I'm afraid you will have to re-write the entire file. Read the content of the file line by line, store it in memory (maybe a vector of strings). Now do your editing on the specified line in that vector. When the operation is complete, dump the entire content of vector in another file. You may later replace the original file.

How to successfully write to a .DAT file contents in a vector using C++?

I'm trying to write to a .DAT file my list of saved patients that are stored in a vector named PatientsInSystem. However, it won't work for some reason. Does anyone know what I might be doing wrong?
if (!PatientsInSystem.empty()) {
cout << "Error. There are still patients checked in. They must be checked out before quitting." << endl;
cout << "Printing remaining patients in the system... " << endl;
for (int i = 0; i < PatientsInSystem.size(); i++) {
cout << "Patient's ID: " << PatientsInSystem.at(i)->getID() << endl;
cout << "Patient's Name: " << PatientsInSystem.at(i)->getFirstName() << " " << PatientsInSystem.at(i)->getLastName() << endl;
cout << "Patient's Birthday: " << PatientsInSystem.at(i)->getBirthDate() << endl;
cout << "Patient's Primary Doctor's ID: " << PatientsInSystem.at(i)->getPrimaryDoctorID() << endl;
}
}
else {
outFile.open("CurrentPatients.dat", ios::out | ios::binary);
if (!outFile.is_open()) {
cout << "File not open." << endl;
}
else {
cout << "Binary file open, saving patients now...\n";
cout << "----------------------------------------\n";
for (int i = 0; i < PatientsInSystem.size(); i++) {
Patient * p;
p = PatientsInSystem.at(i);
outFile.write(reinterpret_cast<char *> (&p), sizeof(p));
}
}
outFile.close();
[This next section of code is the same as above only edited after the first amount of help received]
Here is the edited version of the code...
PatientList is my temporary vector which must be emptied for PatientsInSystem vector to write to the file
case 'q': {
if (!PatientList.empty()) {
cout << "Error. There are still patients checked in. They must be checked out before quitting." << endl;
cout << "Printing remaining patients in the system... " << endl;
for (int i = 0; i < PatientList.size(); i++) {
cout << "Patient's ID: " << PatientList.at(i)->getID() << endl;
cout << "Patient's Name: " << PatientList.at(i)->getFirstName() << " " << PatientList.at(i)->getLastName() << endl;
cout << "Patient's Birthday: " << PatientList.at(i)->getBirthDate() << endl;
cout << "Patient's Primary Doctor's ID: " << PatientList.at(i)->getPrimaryDoctorID() << endl;
}
}
else {
outFile.open("CurrentPatients.dat", ios::out | ios::binary);
if (!outFile.is_open()) {
cout << "File not open." << endl;
}
else {
cout << "Binary file open, saving patients now...\n";
cout << "----------------------------------------\n";
for (int i = 0; i < PatientsInSystem.size(); i++) {
outFile.write(reinterpret_cast<char *> (PatientsInSystem.at(i)), sizeof(Patient));
}
}
outFile.close();
Is there a reason you are using an array of pointers vs a flat array of structs?
You are writing the local pointer variable p, instead of the Patient data. You would just pass p instead of &p (or just pass .at() directly), and the bytes parameter should be sizeof(Patient).
If these are pointers to different sized derived classes, this has issues.
Also, the loop won't every be entered, because its in the block entered when .empty() is true.

C++ String Array search outputs for every item

I know it's somewhat confusing this title of question but I really need help.
I need to find a string in array with many strings. If the string is not found then the appropriate message is showed. However when I use for loop, it then shows this message for every string in array which is not found although it also shows found string... I hope you understand what I mean and sorry if i'm not making sense. here's my code:
void Store::search() {
string name;
cout << "Enter name of product you're searching: " << endl;
getline(cin, name);
for (int i = 0; i < quantity; i++) {
if (name.compare(database[i].name) == 0){
cout << "-------------<Product found!>-------------" << endl;
cout << "name: " << database[i].name << endl;
cout << "supplier: " << database[i].supplier << endl;
cout << "available quantity: " << database[i].quantity<< endl;
cout << "price per unit: " << database[i].price<< endl;
cout << "------------------------------------------" << endl;
}
else
{
cout << "Product doesn't exist in database!" << endl;
}
}
}
The code works for searching but how do I stop the output "Product doesn't exist in database!" for every item in array that is not found(even when searched item is found)?
Thank You in advance
You can use statement flag:
void Store::search()
{
string name;
bool found = false
cout << "Enter name of product you're searching: " << endl;
getline(cin, name);
for (int i = 0; i < quantity; i++)
{
if (name.compare(database[i].name) == 0){
cout << "-------------<Product found!>-------------" << endl;
cout << "name: " << database[i].name << endl;
cout << "supplier: " << database[i].supplier << endl;
cout << "available quantity: " << database[i].quantity<< endl;
cout << "price per unit: " << database[i].price<< endl;
cout << "------------------------------------------" << endl;
found = true;
break;
}
if (!found)
cout << "Product doesn't exist in database!" << endl;
}
You can also use std::find_if, which will make your code look something like:
auto it = std::find_if(databases.begin(), databases.end(), [&name](const auto &database) {return name.compare(database.name) == 0; });
if (it != databases.end())
{
cout << it->name << endl;
cout << "found" << endl;
}
else
{
cout << "not found" << endl;
}
Generally speaking, C++ offers many such features that more often than not will make your code shorter, improve readability and guarantee functionality
You can:
1. keep a bool variable to be set to true if the item is found in the for loop
2. add a break to immediately exit for loop when item is found
3. remove the else part, because it will print out "Product doesn't exist in database!" for each loop cycle if the item does not match
4. after the for loop, check if found is false to check if item does not exist in collection
bool found = false;
for (int i = 0; i < quantity; i++)
{
if (name.compare(database[i].name) == 0)
{
cout << "-------------<Product found!>-------------" << endl;
cout << "name: " << database[i].name << endl;
cout << "supplier: " << database[i].supplier << endl;
cout << "available quantity: " << database[i].quantity<< endl;
cout << "price per unit: " << database[i].price<< endl;
cout << "------------------------------------------" << endl;
found = true; // set "found" to true
break; // add a break to immediately exit for loop when item is found
}
}
if (!found)
{
cout << "Product doesn't exist in database!" << endl;
}
I assume you want to search a product in the database and print its details if found. Otherwise you want to notify user that the product was not found. If I understood you correctly, then you need to move the else statement out of 'for' loop, e.g.:
void Store::search() {
string name;
cout << "Enter name of product you're searching: " << endl;
getline(cin, name);
bool found = false;
for (int i = 0; i < quantity; i++) {
if (name.compare(database[i].name) == 0){
cout << "-------------<Product found!>-------------" << endl;
cout << "name: " << database[i].name << endl;
cout << "supplier: " << database[i].supplier << endl;
cout << "available quantity: " << database[i].quantity<< endl;
cout << "price per unit: " << database[i].price<< endl;
cout << "------------------------------------------" << endl;
found = true;
break;
}
}
if (!found)
{
cout << "Product doesn't exist in database!" << endl;
}
}
If your database may contain more products with the same name, remove 'break;' statement.
A more "modern C++" approach is to leverage the C++ algorithms (such as std::find_if), lambdas and maybe the auto specifier.
As example (assuming database is a std::vector or some kind of STL container):
auto it = std::find_if(database.begin(), database.end(), [&name](const auto& item) { return name.compare(item.name) == 0; });
if (it != database.end())
{
cout << it->name << endl;
cout << "found" << endl;
}
else
{
cout << "not found" << endl;
}

C++ Program need help to debug

#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
struct football_game
{
string visit_team;
int home_score;
int visit_score;
};
void printMenu();
int main()
{
int i, totalValues = 0;
ifstream inputFile;
string temp = "";
inputFile.open("games.txt");
if (!inputFile)
{
cout << "Error opening Input file!" << endl;
exit(101);
}
inputFile >> totalValues;
getline(inputFile, temp);
cout << " *** Football Game Scores *** " << endl << endl;
cout << " * Total Number of teams : " << totalValues << endl << endl;
football_game* records = new football_game[totalValues];
// while (!inputFile.eof())
// {// == NULL) {
for (i = 0; i < totalValues; i++)
{
getline(inputFile, records[i].visit_team);
cout << records[i].visit_team << endl;
inputFile >> records[i].home_score >> records[i].visit_score;
cout << records[i].home_score << " " << records[i].visit_score << endl;
getline(inputFile, temp);
}
//}
cout << endl;
int choice = 0;
int avg_home_Score = 0;
int avg_visit_Score = 0;
printMenu(); // prints menu
cout << "Please Enter a choice from the Menu : ";
cin >> choice;
cout << endl << endl;
while (true)
{
switch (choice)
{
case 1:
cout << " Score Table " << endl;
cout << " ***********************" << endl << endl;
cout << " VISIT_TEAM"
<< " "
<< " HIGH_SCORE"
<< " "
<< "VISIT_SCORE " << endl;
cout << " -----------"
<< " "
<< "-----------"
<< " "
<< "------------" << endl;
for (int i = 0; i < totalValues; i++)
{
cout << '|' << setw(18) << left << records[i].visit_team << " " << '|'
<< setw(7) << right << records[i].home_score << " " << '|' << setw(7)
<< right << records[i].visit_score << " " << '|' << endl;
}
cout << endl << endl << endl;
break;
case 2:
{
string team_name;
cout << "Enter the Team Name : ";
cin >> team_name;
for (int i = 0; i < totalValues; i++)
{
if (records[i].visit_team == team_name)
{
cout << " VISIT_TEAM"
<< " "
<< " HIGH_SCORE"
<< " "
<< "VISIT_SCORE " << endl;
cout << " -----------"
<< " "
<< "-----------"
<< " "
<< "------------" << endl;
cout << '|' << setw(18) << left << records[i].visit_team << " " << '|'
<< setw(7) << right << records[i].home_score << " " << '|'
<< setw(7) << right << records[i].visit_score << " " << '|'
<< endl;
}
}
cout << endl;
break;
}
case 3:
{
for (int i = 0; i < totalValues; i++)
avg_home_Score += records[i].home_score;
cout << "Average home_score: " << (avg_home_Score / totalValues) << endl << endl;
break;
}
case 4:
{
for (int i = 0; i < totalValues; i++)
avg_visit_Score += records[i].visit_score;
cout << "Average visit_score: " << (avg_visit_Score / totalValues) << endl << endl;
break;
}
default:
{
cout << "Please enter valid input !!" << endl;
break;
}
}
printMenu();
cin >> choice;
}
return 0;
}
void printMenu()
{
cout << " Menu Options " << endl;
cout << " ================ " << endl;
cout << " 1. Print Information of all Games[Table Form] " << endl;
cout << " 2. Print Information of a Specific Game " << endl;
cout << " 3. Print Average points scored by the Home Team during season" << endl;
cout << " 4. Print Average points scored against the Home Team" << endl << endl << endl;
}
Here is the input file i am using
games.txt
5
SD Mines
21 17
Northern State
10 3
BYU
10 21
Creighton
14 7
Sam Houston State
14 24
When i am using the 2nd option (Print Information of a Specific Game) from the output screen,
it ask me to enter the team name and when i enter the team-name.
For example: SD Mines it gives me an error, but when I enter the team-name with no space like: BYU it works fine for me.
cin >> team_name;
Takes the input only upto space.
You might want to use cin.getline() for taking space separated strings as input.
A small program demonstrating the same :
#include <iostream>
#include <string>
int main ()
{
std::string name;
std::cout << "Please, enter your full name: ";
std::getline (std::cin,name);
std::cout << "Name is : , " << name << "!\n";
return 0;
}
std::cin ignores whitespaces by default.
To include spaces in your input try :
getline(cin, team_name);
This would pick up all the characters in a line until you press enter. This is available in
#include<string>
You need to flush the std::cin buffer after reading the choice:
#include <limits>
//...
cin >> choice;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Refer to this question for detailed explanation.
Also, if you want to read strings with spaces from the standard input, replace this:
cin >> team_name;
with this:
getline(cin, team_name);
as already mentioned in other answers. No need to flush std::cin this time, since you have already read the full line.
Finally, remove extra newlines from your games.txt:
5
SD Mines
21 17
Northern State
...

Must have pointer to object type c++ (Array)

I have a pointer to object error type for the variable "carrierTime" i have created. If i make this an array, carrierTime becomes an error in the first if statement, however if i leave it without any array i get an error on the last line of the code where i have used carrierTime in a multiplication.
can anyone help??
platform used:visual studios
#include "AMcore.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main()
{
cout << "Amplitude Modulation Coursework" << endl;
cout << "Name: Mohammad Faizan Shah" << endl;
cout << "Student ID: 5526734 \n\n\n" << endl;
std::ifstream file,file2;
string filename1,filename2;
int rowCounter = 0;
double informationTime;
double informationAmplitudeAmount[361];
long double carrierTime;
double carrierAmplitudeAmount[361];
double totalAmplitudeAmount[1000];
int plotPoint;
cout << "Please enter the filename of the Carrier wave \n" << endl;
cin >> filename1;
file.open("carrier.txt");
if (file.is_open())
{
file >> carrierTime;
while (!file.fail())
{
cout << "row" << setw(3) << rowCounter;
cout << " Time = " << setw(5) << carrierTime;
file >> carrierAmplitudeAmount[rowCounter];
rowCounter++;
if (!file.fail())
{
cout << " Carrier signal= " << setw(5) << carrierAmplitudeAmount;
file >> carrierTime;
}
cout << endl;
}
if (file.eof())
cout << "Reached the end of file marker" << endl;
else
cout << "Error whilst reading input file" << endl;
}
else
{
cout << "Error opening input file, ";
cout << "check carrier.txt exists in the current directory." << endl;
}
file.close();
cout << "\n\n" << endl;
cout << "Please enter the filename of the information wave \n\n\n" << endl;
cin >> filename2;
file2.open("information.txt");
if (file2.is_open())
{
file2 >> informationTime;
while (!file2.fail())
{
cout << "row" << setw(3) << rowCounter;
cout << " Time = " << setw(5) << informationTime;
file2 >> informationAmplitudeAmount[361];
rowCounter++;
if (!file2.fail())
{
cout << " Carrier signal= " << setw(5) << informationAmplitudeAmount;
file2 >> informationTime;
}
cout << endl;
}
if (file2.eof())
cout << "Reached the end of file marker" << endl;
else
cout << "Error whilst reading input file" << endl;
}
else
{
cout << "Error opening input file, ";
cout << "check carrier.txt exists in the current directory." << endl;
}
file.close();
cout << "Reading from txt file has completed" << endl << endl;
cout << "\n\n" << endl;
cout << "\n\n" << endl;
cout << "please enter number of sample points to plot:| \n" << endl;
do{
cin >> plotPoint;
if (plotPoint <= 361)
{
cout << "\n plotting the graph.\n" << endl;
}
else if (plotPoint > 361)
{
cout << "Value is too high.. Try value lower than 361\n" << endl;
}
} while (plotPoint > 361);
cout << "row" << setw(3) << rowCounter;
file >> carrierAmplitudeAmount[361];
rowCounter++;
plotPoint = 361 / plotPoint;
cout << " Time \| Amplitude Modulation plot\n------------+--------------------------------------------------\n";
totalAmplitudeAmount[0] = carrierAmplitudeAmount[0] * informationAmplitudeAmount[0];
cout << setw(6) << carrierTime << setw(4) << "\|" << setw(48) << "*" << totalAmplitudeAmount[0] << endl;
for (int i = 1; i <= 361; i = i + plotPoint) {
totalAmplitudeAmount[i] = informationAmplitudeAmount[i] * carrierAmplitudeAmount[i];
int y = totalAmplitudeAmount[i] * 22;
cout << setw(6) << carrierTime[i++] << setw(4) << "\|" << setw(26 + y) << "*" << totalAmplitudeAmount[i] << endl;
}
cout << "End of program" << endl;
system("pause");
return 0;
}
cout << setw(6) << carrierTime[i++] << setw(4) << "\|" << setw(26 + y) << "*" << totalAmplitudeAmount[i] << endl;
carrierTime[i++] does not look correct. The variable is not defined as a pointer.
Also, proper debugging would help you catch these errors for yourself.