Searching for an Integer in an Output File C++ - c++

I'm currently writing a menu driven program in C++ and I'm having a little difficulty searching for a certain int in an Output file. My function looks like this.
int studentId;
int searchId;
double examGrade1, examGrade2, examGrade3;
ifstream readGrades;
do
{
cout << "Enter the student ID: ";
cin >> searchId;
if (searchId < 0 || searchId > 9999) {
cout << "Your student ID must be in between 0 and 9999! Try again...\n";
}
} while (searchId < 0 || searchId > 9999);
readGrades.open("grades.txt");
if (readGrades)
{
system("cls");
while (readGrades >> studentId >> examGrade1 >> examGrade2 >> examGrade3)
{
if (searchId == studentId)
{
cout << left
<< "Student ID\t" << "Exam 1\t" << "Exam 2\t" << "Exam 3\t" << endl;
cout << "======================================" << endl;
cout << left << setw(4) << studentId << "\t\t"
<< fixed << setprecision(2)
<< left << setw(5) << examGrade1 << "\t"
<< left << setw(5) << examGrade2 << "\t"
<< left << setw(5) << examGrade3 << endl;
system("pause");
break;
}
else
cout << "Entered ID not found";
}
}
else
{
cout << "Error opening file!\n";
}
cout << endl; }
Now the problem is the else statement. I am supposed to prompt to the user that a certain ID doesn't exist. But I don't know how to make the else statement only run once in the while statement. Every time I search a non-existing ID, it will say "Entered ID not found" for however many times it reads the inputs.
So the results look something like this.
No ID Found
At the same time, if I enter an ID that does exist but it's third in the file, it will look something like this. ID Found
I know logically what is happening, it keeps running the while loop for however many times. But I don't know how to deal with the problem. Any help to lead me to the right direction would be helpful. I'm new to coding/C++ and not too familiar with searching for something inside a file. Thank you!

The else block is in the wrong place. You need to update your logic such that you print that message only if the student ID is not found after going through the entire file. Which means, it has be outside the while loop.
if (readGrades)
{
bool found = false;
while (readGrades >> studentId >> examGrade1 >> examGrade2 >> examGrade3)
{
if (searchId == studentId)
{
cout << left
<< "Student ID\t" << "Exam 1\t" << "Exam 2\t" << "Exam 3\t" << endl;
cout << "======================================" << endl;
cout << left << setw(4) << studentId << "\t\t"
<< fixed << setprecision(2)
<< left << setw(5) << examGrade1 << "\t"
<< left << setw(5) << examGrade2 << "\t"
<< left << setw(5) << examGrade3 << endl;
found = true;
break;
}
}
if ( !found )
{
cout << "Entered ID not found";
}
}

Related

I am trying to polish my output using (setw) but if the value that i enter differ in range it does not work properly

I am trying to fix my output using setw(4).I have tried different a range of number between 1 to 10 but none get me the desired output.
void Students(int& size_public)
{
cout << "Input the number of information to be entered: ";
cin >> size_public;
cout << endl << endl;
// Reseting the screen
system("cls");
for (int i = 0; i < size_public; i++)
{
cout << "________________________Enter the following information for the data to be stored________________________\n" << endl;
cout << "Name: ";
cin >> employees[i].name_public;
cout << "Age: ";
cin >> employees[i].age_public;
cout << "ID.No: ";
cin >> employees[i].ID_No_publice;
cout << endl;
system("cls");
}
}
void Students(Employee employees[arraysize], int& size_public)
{
for (int i = 0; i < size_public; i++)
{
if (i == 0)
{
cout << setw(10) << "Name\t" << "Age\t" << "ID.No" << endl << endl;
}
cout << setw(10) << employees[i].name_public << '\t'
<< employees[i].age_public << '\t'
<< employees[i].ID_No_publice << endl;
}
}
};
Later in the program it is called
if (selection == 2)
{
student.Students(size);
cout << "1. Leave\n";
cout << "2. Showinformation\n";
cout << "\n________________________________________________\n";
cout << "Enter your choice: ";
cin >> choice;
cout << "\n________________________________________________\n";
if (choice == 1)
{
cout << endl;
}
else if (choice == 2)
{
student.Students(student.employees, size);
}
else if (choice != 1 && choice != 2)
{
cout << "choice is not found\n";
}
}
This is what I am talking about
Name Age ID.No
fge 33 345674
sdfgfd 34 23
dfghjkjhg 354 54345
Space behind the names is what I am trying to avoid
This is the output i receive when i use setw(10)
and this is what happen when the range of input changes
Name Age ID.No
afjghbslkk;jfl 2 3
fg 3 5.67654e+06
3 34543 543
if you look at fg in name it has a space behind it and I am trying to avoid it
My desired output is something like
Name age ID.No
dfghsgffgdf 44553 4564564
ajkghjkgh 444 465454
ff 4 46
I do not know if it is possible but if I am missing any thing just let me know and i will update the code.
Example
if (i == 0)
cout << left << setw(10) << "Name" << setw(10) << "Age" << setw(10) << "ID.No" << endl << endl;
cout << left << setw(10) << employees[i].name_public
<< setw(10) << employees[i].age_public
<< setw(10) << employees[i].ID_No_publice << endl;
See if this is what you need.

setw(n) and alignment not working the way I need it to - C++

Here is my code for context. This is my second homework assignment intro to programming course and I have used everything we've learned in this assignment. I am not allowed to use anything I have not learned.
The part I am concerned with is the output at the very bottom (commented as information output). Currently, I am struggling to get everything perfectly right aligned (the last letter or number in the right hand column must align with each other as if I were typing them from the right.
Everything except the patient's name, room type, and days spent in the hospital are aligning properly, decimals aligned and everything. Changing the setw(10) to anything larger does nothing beneficial (ex: i had all of them to setw(40) and it still did not align anything properly. Any ideas?
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
//constants
const float PRIVATE = 125.00;
const float SEMI = 95.00;
const float WARD = 75.00;
const float TV = 3.50;
const float PHONE = 1.75;
int main()
{ //local variables
string fname, lname, roomType, tvAccess, phoneAccess;
int id, days;
float roomBill, roomPrice, tvCharge, phoneCharge;
bool error = false;
//data collection/output
cout << "Welcome to the hospital self-service program. Your bill will be calculated here.\n\n" << endl;
cout << "Please enter your first and last name: ";
cin >> fname;
cin >> lname;
cout << fname << " " << lname << ", please enter the four digit identification number found on your hospital wristband: ";
cin >> id;
cout << "Please enter the number of days spent in the hospital: ";
cin >> days;
cout << "\nEnter the type of room you stayed in: \nEnter P for room type: Private \nEnter S for room type: Semi-Private\nEnter W for room type: Ward \n" << endl;
cin >> roomType;
cout << "\nDid your room come with access to Television? Y/N: ";
cin >> tvAccess;
cout << "Did your room come with access to a Telephone? Y/N: ";
cin >> phoneAccess;
//if and elses
if (roomType == "P" || roomType == "p")
{
error = false;
roomType = "Private Room";
roomPrice = PRIVATE;
}
else if (roomType == "S" || roomType == "s")
{
error = false;
roomType = "Semi-Private Room";
roomPrice = SEMI;
}
else if (roomType == "W" || roomType == "w")
{
error = false;
roomType = "Ward Room";
roomPrice = WARD;
}
else
{
cout << "Room type not valid. Exit the program and try again." << endl;
error = true;
}
if (tvAccess == "Y" || tvAccess == "y")
tvCharge = TV;
else
tvCharge = 0;
if (phoneAccess == "Y" || phoneAccess == "y")
phoneCharge = PHONE;
else
phoneCharge = 0;
//information output
cout << fixed << setprecision(2) << showpoint << endl;
cout << setw(24) << left << "\n\nPatient Full Name: " << setw(10) << right << fname << " " << lname << endl;
cout << setw(24) << left << "Identification Number: " << setw(10) << right << id << endl;
cout << setw(24) << left << "Days spent in hospital: " << setw(10) << right << days << " day(s)" << endl;
cout << setw(24) << left << "Room Type: " << setw(10) << right << roomType << endl;
cout << setw(24) << left << "Room Charge: " << setw(10) << right << roomPrice * days << endl;
cout << setw(24) << left << "Television Charge: " << setw(10) << right << tvCharge * days << endl;
cout << setw(24) << left << "Telephone Charge: " << setw(10) << right << phoneCharge * days << endl;
cout << setw(24) << left << "Total Charge: " << setw(10) << right << days * (phoneCharge + tvCharge + roomPrice) << endl;
system("pause");
return 0;
}
for clarification.
The reason, they are not formatted correctly, is, that the setw in
setw(10) << right << fname << " " << lname << endl;
and
setw(10) << right << days << " day(s)" << endl;
only applies to the first variable, i.e. fname and days. Everything else is just appended. You need to concatenate these strings first before using setw here.

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;
}

Displaying Array Data From a File using For Loop [C++]

Doing an assignment and struggling hard. I think I've narrowed down my problem to the for loop. Can anyone explain how to fix this? I can't find an answer on google or here that's helping me get it. I have to make an array of some data files I was given. Then use a for loop to display the results. The input is:
1/8/2016,98.550003,96.959999,70798000
1/11/2016,98.970001,98.529999,49739400
1/12/2016,100.550003,99.959999,49154200
etc.
The expected output should be clean numbers like above.
The observed output is a mess of numbers that's way too big.
//Variable Declaration
const int SIZE = 400;
double stockOpen[SIZE];
double stockClose[SIZE];
double stkCloseAVG=0;
double minStkClose;
double maxStkClose;
int stockVolume[SIZE];
int i = 0;
string name = "r";
string stockDate[SIZE];
string stockName;
string filename;
ifstream in;
string stkDate, stkOpen, stkClose, stkVol;
int actSize;
cout << "Welcome to " << name << "'s stock majigger thingy!" << endl;
cout << "Please enter the stock name (aapl; spy)" << endl;
cin >> stockName;
filename = stockName + ".table.csv";
in.open(filename.c_str());
if (!in)
{
cout << "File Error! Please try again! I BELIEVE IN YOU, LOVE!" << endl;
system("pause");
exit(-1);
}
while (!(in.eof()) && i < SIZE)
{
getline(in, stkDate, ',');
getline(in, stkOpen, ',');
getline(in, stkClose, ',');
getline(in, stkVol, '\n');
i++;
// Check:cout << stkDate << endl <<endl<< stkOpen<<endl << stkClose<<endl << stkVol;
//system("pause");
}
actSize = i;
//system("clr");
for (int i=0; i < actSize; i++) // <- Need help here
{
cout << "Stock Daily Performance Report -" << stockName << endl;
cout << setw(10) << "Date" << setw(7) << "Open" << setw(7) << "Close" << setw(11) << "Volume" << endl;
cout << setw(10) << stockDate[i] << fixed << setprecision(2) << setw(7) << stockOpen[i] << setw(7) << stockClose[i] << fixed << setprecision(0) << setw(11) << stockVolume[i] << endl;
stkCloseAVG= stkCloseAVG + stockClose[i];
minStkClose = stockClose[1];
maxStkClose = stockClose[1];
if (stockClose[i] < minStkClose)
minStkClose = stockClose[i];
if (stockClose[i] > maxStkClose)
maxStkClose = stockClose[i];
}
cout << "Stock Price" << endl;
cout << endl;
cout << "Average" << setw(5) << stkCloseAVG << endl;
cout << "Minimum" << setw(5) << minStkClose << endl;
cout << "Maximum" << setw(5) << maxStkClose << endl;
system("pause");
return 0;

How do I validate integer input?

So I was just making this little calculator program for a game my brother plays just because I was bored. I took a c++ course last semester in college (now taking a java course which I find a bit more confusing) and I just found it fun to make these little programs. Well like usual I'm getting carried away and must be a perfectionist and this is really bothering me.
Now in this game, and like in real life, numbers are seperated by commas to obviously make it easier to read. Because of this, that's mostly how numbers are going to be inputted into the calculator by my brother. Now I could just tell him to not put in any commas when typing in the number and put it in the prompt that there should not be any commas but even then you can't be sure. Even so, it would be best if the code just doesn't mess up every time something that's not a number is put in.
What I've got so far is pretty good. if you put in just letters it will prompt the user again and if you put letters in AFTER the numbers only (not inbetween, that messes it up i found) then it will ignore those letters and work properly. If you put in commas though, it always returns the same thing (0 and 5) although that could be what I'm putting in. I have no idea if the comma is acting as a cut off point or what. Here's the code for getting the integers:
#include <iostream>
using namespace std;
int main() {
int numberofbones, amountofxp, comparableDrag, comparableBaby, comparableDragNoAltar, comparableBigNoAltar, comparableBabyNoAltar;
double comparableBig;
char Gildedaltar, BoneSelection, replay;
bool bFail;
do{
cout << "How many bones do you have?: ";
cin >> numberofbones;
bFail = cin.fail();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while (bFail == true);
do{
cout << "How much XP do you need?: ";
cin >> amountofxp;
bFail = cin.fail();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while (bFail == true);
cout << "Are you using a Gilded Altar? (Y/N) ";
prompt:
cin >> Gildedaltar;
comparableDrag = amountofxp / 252;
comparableBig = amountofxp / 52.5;
comparableBaby = amountofxp / 105;
comparableDragNoAltar = amountofxp / 72;
comparableBigNoAltar = amountofxp / 15;
comparableBabyNoAltar = amountofxp / 30;
if (Gildedaltar == 'y' || Gildedaltar == 'Y') {
system("cls");
cout << "What bones will you be using: " << endl;
cout << "a) Dragon Bones " << endl;
cout << "b) Big Bones " << endl;
cout << "c) BabyDragon Bones " << endl;
cin >> BoneSelection;
if (BoneSelection == 'a' || BoneSelection == 'A') {
cout << endl << "With Dragon Bones you need " << comparableDrag << " Bones" << endl;
if (comparableDrag < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableDrag << " left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableDrag - numberofbones << " more bones" << endl;
}
}
if (BoneSelection == 'b' || BoneSelection == 'B') {
cout << endl << "With Big Bones you need a total of " << comparableBig << " Bones" << endl;
if (comparableBig < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBig << " Left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBig - numberofbones << " more bones" << endl;
}
}
if (BoneSelection == 'c' || BoneSelection == 'C') {
cout << endl << "With BabyDragon Bones you will need " << comparableBaby << " Bones" << endl;
if (comparableBaby < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBaby << " left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBaby - numberofbones << " more bones" << endl;
}
}
}
else if (Gildedaltar == 'n' || Gildedaltar == 'N') {
system("cls");
cout << "What bones will you be using: " << endl;
cout << "a) Dragon Bones " << endl;
cout << "b) Big Bones " << endl;
cout << "c) BabyDragon Bones " << endl;
cin >> BoneSelection;
if (BoneSelection == 'a' || BoneSelection == 'A') {
cout << endl << "With Dragon Bones, you will need " << comparableDragNoAltar << " Bones " << endl;
if (comparableDragNoAltar < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableDragNoAltar << " left over, get to sacrafising!" << endl;
}
else {
cout << "You will neeed " << comparableDragNoAltar - numberofbones << " More bones" << endl;
}
}
if (BoneSelection == 'b' || BoneSelection == 'B') {
cout << endl << "With Big Bones, you will need " << comparableBigNoAltar << " Bones" << endl;
if (comparableBigNoAltar < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBigNoAltar << " Left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBigNoAltar - numberofbones << " More bones" << endl;
}
}
if (BoneSelection == 'c' || BoneSelection == 'c') {
cout << endl << "With BabyDragon Bones, you will need " << comparableBabyNoAltar << " Bones" << endl;
if (comparableBabyNoAltar < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBabyNoAltar << " Left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBigNoAltar - numberofbones << " More Bones" << endl;
}
}
}
else {
goto prompt;
}
}
You can ignore most of the code, I know it probably looks really sloppy and there's probably much betters ways of handling most of the things in here. I just decided to make this out of boredom and figured it could be a good lesson to learn from for me. if you know of a way to help me I would be more than happy to hear the solution, if there's a way to get the program to ignore the commas completly that would be even better but alas I don't believe there's a way to do that.
P.S. please don't get too technical with me, I've only taken one course on this stuff :) Thanks in advance for the help.
You just need to remove the commas from the input string before trying to get an int from it. Better would be to remove any non-digit chars from the input, which you can do with isdigit(). Then call atoi() on it.
string& remove_nondigit(string& s) {
s.erase(remove_if(s.begin(), s.end(), [](const char& c) {
return !isdigit(c);
}), s.end());
return s;
}
yourF() {
string sBones;
cin >> sBones;
cout >> remove_nondigit(sBones);
// you'll want to use atoi() on sBones
}