I'm having problem with the string input, the program stops running whenever i enter a string and also if possible kindly fix my statements on the records because they don't seem to work well. Also, how do i delete a string? I tried to replace it with 'none' here for a sample. Thank you in advance!
Here is my code:
#include <iostream>
using namespace std;
int main(){
//Initializing
char choice;
int i, j, record=0, totalrecord;
int id[record];
string name[record];
double price[record];
bool back=true;
string none;
//Menu
while(back=true){
cout<<"*******************************"<<endl;
cout<<"[A] Add Record"<<endl;
cout<<"[V] View Record"<<endl;
cout<<"[E] Edit Record"<<endl;
cout<<"[D] Delete Record"<<endl;
cout<<"[L] View All Record"<<endl;
cout<<"Enter your choice and press return: "<<endl;
cin >> choice;
switch (choice){
//Add Record
case 'a':
case 'A':
record++;
cout<<"Input ID: ";
cin>>id[record];
cout<<"Input Name: ";
cin>>name[record];
cout<<"Input Price: ";
cin>>price[record];
break;
//View Record
case 'v':
case 'V':
cout<<"Enter ID you wish to view: ";
cin>>id[record];
cout<<"ID Name Price"<<endl;
cout<<id[record]<<" "<<name[record]<<" "<<price[record]<<endl;
break;
//Edit Record
case 'e':
case 'E':
cout << "Enter ID you wish to edit: ";
cin>>id[record];
cout<<"Input NEW name: ";
cin>>name[record];
cout<<"Input NEW price: ";
cin>>price[record];
break;
//Delete Record
case 'd':
case 'D':
cout << "Enter ID you wish to delete";
cin>>id[record];
id[record]=0;
name[record]=none;
price[record]=0;
break;
//View All Records
case 'l':
case 'L':
cout<<"ID Name Price"<<endl;
for(i=1; i<totalrecord+1; i++){
cout<<id[i]<<" "<<name[i]<<" "<<price[i]<<endl;
}
break;
//Exit Program if invalid input
default:
back=false;
break;
}
}
return 0;
}
Well, one problem is that here:
int i, j, record=0, totalrecord;
int id[record];
string name[record];
double price[record];
You are trying to create variable length arrays, which isn't supported in C++. Not only that, but even if it were supported you would be creating an array of size 0, since record = 0.
Thus, you need a compile-time constant value for the size of the array that isn't 0.
constexpr std::size_t RECORD_SIZE = 100; // make this any other that isn't less than or equal to 0
Then, you can create your array like this
int id[RECORD_SIZE];
string name[RECORD_SIZE];
double price[RECORD_SIZE];
However, one problem with this strategy is that if you want have an amount of records that exceed the RECORD_SIZE since you can't resize the array. Thus, I recommend that you see my final point.
Your logic when viewing, editing, and deleting a record is also incorrect since you always access an invalid index as the value of record will point to an empty slot so long as the array isn't full. Not only that, but there is no error checking.
Nonetheless, I assume you wanted to do those operations based on an index.
std::size_t index = 0;
std::cin >> index;
Then for the viewing and editing operations you would use that index to manipulate the records.
For the deleting operation, you would have to shift the records that are to the right of the deletion point left.
However, for these tasks I'd ultimately recommend that you use std::vector because it has support for all the operations you require and because it has a much greater dynamic capacity.
Related
I am trying to make a really simple text menu of sorts using switch statements for a class assignment. The issue is when calling the various functions I've made in the different cases of the switch statement, the never seem to end.
Considering the same issue seems to be happening to all the functions in my switch statement I think it might have something to do with the switch statement itself and not the individual functions although I honestly don't know at this point.
Disclaimer: I know I have tons of other issues with my code, but im just trying to pick a big one for simplicity. I would appreciate advice on other parts of my code aswell. (Also its not done yet as you can probably see by the unfinished cases)
Example output:
==================
1. Admission's Office
2. Student
3. End Program
==================
Enter your choice: 1
Enter the password: 123
******************
1. Add a new student
2. Add new students from a file
3. Drop a student
4. View one students info
5. View all students info
******************
Enter your choice: 1
Enter the first name: First Name
Enter the last name: Last Name
Enter the gender: m
Enter the first name: It should only ask me once
Enter the last name: Why is this looping?
Enter the gender: ????
Enter the first name:
Enter the last name: ???????
Enter the gender: a
Enter the first name: ^C
Code
//main.cpp
int main() {
Student stuAr[SIZE];
int choice, password, userInput;
int numStu = 0;
bool valid;
do {
userMenu();
cin>>choice;
cout<<endl;
switch(choice){
case 1:
cout<<"Enter the password: ";
cin>>password;
cout<<endl;
valid = checkPass(password);
if (valid) {
adminMenu();
cin>>choice;
cout<<endl;
do {
switch(choice) {
case 1:
addStu(stuAr, numStu);
break;
case 2:
addStuFile(stuAr, numStu);
break;
case 3:
cout<<"Enter the student ID: ";
cin>>userInput;
cout<<endl;
dropStu(stuAr, numStu, userInput);
break;
case 4:
cout<<"Enter the student ID: ";
cin>>userInput;
cout<<endl;
viewStu(stuAr, numStu, userInput);
break;
case 5:
viewAllStu(stuAr, numStu);
break;
}
}while(choice != 6);
}
else {
cout<<"The password is wrong."<<endl;
}
break;
case 2:
break;
}
}while(choice != 3);
return 0;
//still main.cpp
//addStu function for case 1 of the nested switch statement
void addStu(Student stuAr[], int& numStu) {
cin.ignore();
cout<<"Enter the first name: ";
stuAr[numStu].setFN();
cout<<endl;
//cin.ignore();
cout<<"Enter the last name: ";
stuAr[numStu].setLN();
cout<<endl;
cout<<"Enter the gender: ";
stuAr[numStu].setGender();
cout<<endl;
numStu++;
return;
}
You are never rereading choice within your inner loop.
if (valid) {
adminMenu();
cin>>choice; // only done once, therefore do loop never terminates
cout<<endl;
do {
switch(choice) {
case 1:
addStu(stuAr, numStu);
break;
// ...
}
// after switch-case, add:
cin >> choice;
cout << endl;
You never change choice in the inner do..while loop, and therefore the condition choice != 6 will always be true, unless you enter it in the first time.
I am new at c++ and for an assignment I have a program that requires a switch within a while but i keep getting stuck in an infinite loop
I have tried looking up ways to solve it but since i am not skilled at c++, it is really hard for me to get my error
#include <iostream>
#include <stdio.h>
using namespace std;
int main(void)
{
float length, width, perimeter, area;
char ans;
cout<<"Please enter the length of the rectangle: \n";
cin>>length;
cout<<"Please enter the width of the rectangle: \n";
cin>>width;
cout<<"What do you wish to do with these values?\n";
cout<<"Choose an option from the menu: \n";
cout<<"1 - Calculate Perimeter\n";
cout<<"2 - Calculate Area\n";
cout<<"3 - Quit\n";
cout<<"Please enter your choice: \n";
cin>>ans;
while (ans != '3')
{
printf("give option: "); //found this online
ans = getchar(); //this too
switch (ans)
{
case '1' :
perimeter=2*(length+width);
cout<<"The perimeter of the rectangle with length "<<length<<" and width "<<width<<" is "<<perimeter<<endl;
break;
case '2' :
area=length*width;
cout<<"The area of the rectangle with length "<<length<<" and width "<<width<<" is "<<area<<endl;
break;
default :
cout<<"Invalid Entry, please only select options from menu"<<endl;
}
}
printf("Program finished...\n"); //this was online too
return 0;
}
when i enter the option 2 or 1, there is an infinite loop and i cant seem to fix that.
I am not use to formatting on this site, please excuse the way i formatted my code
getchar() is not the right function to use there. It returns all characters, spaces, newlines, etc.
If you add a line to output the value of ans right after that, you will notice all the values that are assigned to ans.
ans = getchar();
cout << "ans: " << (int)ans << endl;
To skip whitespaces from the stream, use
cin >> ans;
In addition, the logic to get ans inside the while loop is flawed. It should be after the switch statement. Otherwise, your program tries to read ans twice before the first execution of the switch statement.
Here's an updated version of the relevant code that works for me.
cout << "Please enter your choice: \n";
cin >> ans;
while (ans != '3')
{
switch (ans)
{
case '1' :
perimeter=2*(length+width);
cout<<"The perimeter of the rectangle with length "<<length<<" and width "<<width<<" is "<<perimeter<<endl;
break;
case '2' :
area=length*width;
cout<<"The area of the rectangle with length "<<length<<" and width "<<width<<" is "<<area<<endl;
break;
default :
cout<<"Invalid Entry, please only select options from menu"<<endl;
}
cout << "Please enter your choice: \n";
cin >> ans;
}
Here is some help regarding formatting : https://stackoverflow.com/editing-help.
Indent the entire code 4 spaces to the right for a code block.
You must also be able to see the preview below as you keep writing the question.
getchar() isn't the appropriate function to use here. Read about the nuance here : http://www.cplusplus.com/forum/general/193480/
cin will be more appropriate to use.
Also, analyse your code step by step. You have an input taking line outside the while loop, and one inside too. Realise why this is wrong and try fixing it.
Since this is an assignment question, I won't be telling you the answer, but hopefully lead you to understand where you are going wrong.
After you solve the problem, please go back and analyse why your original code did not work. It helps immensely.
How can I store my input in the following catagories i.e water,domestic etc.When I give information about water birds then I give information about domestic birds.but 2nd information overrides the first one.Is there any way to store data for catagory wise?
/* declaring header files */
#include<iostream>
#include<conio.h>
#include<stdio.h>
#include <fstream>
#include <bits/stdc++.h>
#include <string>
using namespace std;
class Bird{
private:
char name[50],colour[50],nature[50],location[50];
float living_duration;
public:
int code;
int set_info(){
char name='\0';
char colour='\0';
char nature='\0';
char location='\0';
float living_duration=0.0;
}
int get_info(){
cout<<"\nEnter bird's name: ";
cin>>name;
cout<<"Colour: ";
cin>>colour;
cout<<"Nature: ";
cin>>nature;
cout<<"Location: ";
cin>>location;
cout<<"Living Duration: ";
cin>>living_duration;
cout<<"Bird's code: ";
cin>>code;
}
int display_info(){
cout<<"\nBird's name: "<<name;
cout<<"\nColour : "<<colour;
cout<<"\nNature : "<<nature;
cout<<"\nlocation : "<<location;
cout<<"\nLiving Duration : "<<living_duration<<" year";
cout<<"\nCode : "<<code;
}
}obj[100];
int main(){
int i,j,k,n,m;
do{
cout<<"\n\nWhat do you want to do\n1.Input bird's information"
<<"\n2.Display\n3.Search\n4.Exit."
<<"\n\nChoose appropriate number: ";
cin>>n;
switch(n){
case 1://bird information
cout<<"Please Select Birds Category"<<endl;
cout<<"------------------"<<endl;
cout<<"1)Water\n2)Domestic\n3)prey\n4)treebased\n5)flightless\n6)migratory\n"<<endl;
cin>>m;
switch(m){
case 1:
cout<<"Enter the number of bird how many to input: ";
cin>>j;
for(i=1;i<=j;i++){
cout<<"\nInformation of Bird "<<i<<".\n";
obj[i].get_info();
}
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
default:
cout<<"Wrong choice!!\nPlease enter correct number.";
break;
}
case 2://display
for(i=1;i<=j;i++)
{
cout<<"\nBird no "<<i<<".\n";
obj[i].display_info();
cout<<"\n";
}
break;
case 3://search
cout<<"\nEnter the bird code: ";
cin>>k;
for(i=1;i<=j;i++)
{
if(k==obj[i].code)
{
cout<<"\nBird no "<<i<<".\n";
obj[i].display_info();
break;
}
}
if(k!=obj[i].code)
cout<<"Wrong code input...\n";
break;
case 4://exit
break;
default:
cout<<"Wrong choice!!\nPlease enter correct number.";
break;
}
}while(n!=4);
}
You need to split your concepts between bird data and a container of data.
In a relational database, you would have tables. Let the columns of a table be represented by the data members of a structure. A record (row) of the table will be an instance of the record structure:
class Bird
{
public:
std::string name;
std::string colour;
std::string nature;
std::string location;
float living_duration;
};
For the container or table, you could use std::vector:
std::vector<Bird> bird_table;
Many relational databases also include index tables to speed up searches. The index table will contain pairs, the key (or column value) and an index into the std::vector. The C++ language has a handy container called a std::map:
std::map<string, unsigned int> name_index;
The string parameter represents the key or column type.
The unsigned int parameter represents the index into the database (a.k.a foreign key).
To retrieve a Bird record by name you access the index table first, then the vector:
unsigned int database_index = name_index["crow"];
Bird crow = database[index];
So I have just learnt input validation however I ran into a problem. I'm forcing the user to enter a number and not a string which works, however if the user enter a number (one that is included in the switch case) and a string then the program crashes. Any tips on what to change so the validation works on everything?
int menu(double pi) //menu for choosing a shape
{
int choice = 0;
cout << "Please select what you wish to calculate:\n\n1 - Area of a Circle\n\n2 - Circumference of a Circle\n\n3 - Area of a Rectangle\n\n4 - Area of a Triangle\n\n5 - Volume of a Cuboid\n\n ";
while (!(cin >> choice))
{
cout << "Invalid input, please enter a number of 1-5\n\n";
cin.clear();
cin.ignore(100, '\n');
}
system("CLS");
switch (choice) //switch case for each shape
{
case 1:
circleArea(pi);
break;
case 2:
circleCircum(pi);
break;
case 3:
rectanArea();
break;
case 4:
triangArea();
break;
case 5:
cubVol();
break;
default:
cout << "Invalid input! Please try again.\n\n";
break;
}
return 0;
}
The issue with using
cin >> choice
When inputting a number is that >> will stop at the first non-numeric input and as long as there was numeric input to begin with it will treat it as a valid read. That means things like 2L, 2.0, and -1T are all valid integer inputs as far as cin is concerned. It just leaves the invalid part in the stream. It is this remaining steam input that messes up the program on the next input operation.
One way to fix this is to read the input into a std::string using getline and then parse the string to make sure it contains valid input. If you want to get a int for instance the
int choice;
std::string input;
std::size_t pos;
do
{
std::cout << "Enter Choice: ";
std::getline(cin,input);
choice = stoi(input, &pos);
} while(pos != input.size());
This makes sure that you read in everything up to the pressing enter into input and that you only stop the loop once everything entered can be converted to a valid int.
I am trying to keep a track of total amount of bought groceries.
In my program, every time I buy apples, cheese, or bread, the program should continue with displaying the menu again.
But it keeps asking "How many apples?" after the program has already calculated the total for the apples instead of going back to the menu to choose another item.
Perhaps it has something to do with the type of loop I have used.
I am stuck on trying to figure this out. Any help would be appreciated.
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
double BUDGET;
const double apple= .60;
const double lb_cheese= 1.60;
const double loaf_bread = 2.50;
double total;
int count;
char choice;
double amount_left;
cout <<"Welcome! What is the budget for your picnic lunch?"<< endl;
cin>> BUDGET;
cout<<"Choose one of the following"<<endl;
cout<<"-------------------------------------"<<endl;
cout<<" MENU \n "<<endl;
cout<<"A-Apple B-Cheese C-Bread"<<endl;
cout<<" $0.60 $1.50 $2.50 "<<endl;
cout<<"-------------------------------------"<<endl;
cin>> choice;
while ((choice != 'Q') && (total <BUDGET)) //Q is the sentinel value to "quit" the program
{
switch(choice)
{
case 'A':
case 'a':
cout<<"How many apples?";
cin>> count;
total+= (count *apple);
break;
case 'B':
case 'b':
cout<<"How many pounds of cheese ?";
cin>> count;
total+= (count* lb_cheese);
break;
case 'C':
case 'c':
cout<<"How many loafs of bread?";
cin>> count;
total+= (count * loaf_bread);
break;
default:
cout<<"The entry you have entered is not valid, please try again."<<endl;
}
if( total > BUDGET)
{ cout<<"You have exceeded your budget please check your cart.\n\n";
break;
}
cout<<"Your total is: $"<<setprecision((2))<<fixed<<total<<endl;
amount_left= BUDGET-total;
cout<<"You have $"<<setprecision(2)<<fixed<<amount_left<<" left to spend."<<endl;
}
return 0;
}
Displaying menu is out of the loop:
display menu
read option
while (option != quit) {
do some calculations
}
and the menu is therefore displayed only once. You could change it to infinite loop:
while (true) {
display menu
read option
if (choice == 'Q' || total >= BUDGET)
break;
do some calculations
}
Also try to avoid writing functions that are longer than 50 lines, place some logic into some different function and just call this function, decompose it to smaller parts, it will be much easier to read and also much easier to understand.
Yes, get the menu in a loop to display it the number of times you desire and also please remember to initialize your variables as good practice.
Double total=0.00 // initialize.