Dynamically Allocating String Arrays - c++

This is what I have so far. I am trying to edit a dynamically allocated array in C++, however, when the for loop runs, it is skipping over the first item. I need it to get all of the items. Any help is appreciated. Thanks in advance.
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
// Declare Variables
int userChoice = 0;
int numItems = 0;
cout << "How many items will be on your list? ";
cin >> numItems;
string *list = new string[numItems];
// Give the user some options
cout << "1. Add Item" << endl;
cout << "2. Remove Item" << endl;
cout << "3. Sort Items" << endl;
cout << "4. Exit" << endl;
cout << "Enter the number of the operation you wish to perform: ";
cin >> userChoice;
cout << endl;
// Perform the operation
switch(userChoice)
{
case 1:
{
cin.clear(); // Remove new line from cin
for(int i = 0; i < numItems; i++)
{
cout << "Item #" << i + 1 << " --> ";
getline(cin, list[i]);
}
}
break;
case 2:
{
}
break;
case 3:
{
}
break;
case 4:
{
return 0;
}
default:
{
cout << "Error! Invalid Selection" << endl;
}
}
// Output the list
cout << "-------Items-------" << endl
<< *list << endl << endl;
// free memory
delete [] list;
cout << "Enter the number of the operation you wish to perform: ";
cin >> userChoice;
return 0;
}

It seems odd to me to be using the STL for some things (like string) and then use a standard array to hold the strings. Also, list is a standard type of object in STL, so that is not a great name for a variable. This revised code fixes your issues with ignoring the first line, and also uses a vector instead of doing new and delete.
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
// Declare Variables
int userChoice = 0;
int numItems = 0;
cout << "How many items will be on your myList? ";
cin >> numItems;
cin.ignore ();
vector<string> myList;
while (true)
{
// Give the user some options
cout << "1. Add Item" << endl;
cout << "2. Remove Item" << endl;
cout << "3. Sort Items" << endl;
cout << "4. Exit" << endl;
cout << "Enter the number of the operation you wish to perform: ";
cin >> userChoice;
cin.ignore ();
cout << endl;
// Perform the operation
switch(userChoice)
{
case 1:
{
for(int i = 0; i < numItems; i++)
{
cout << "Item #" << i + 1 << " --> ";
string s;
getline(cin, s);
myList.push_back (s);
}
}
break;
case 2:
{
}
break;
case 3:
{
sort (myList.begin (), myList.end ());
}
break;
case 4:
{
return 0;
}
default:
{
cout << "Error! Invalid Selection" << endl;
}
}
// Output the myList
cout << "-------Items-------" << endl;
copy(myList.begin(), myList.end(), ostream_iterator<string>(cout, "\n"));
} // end of while
}
The project description explicitly says I can't use standard containers, sort functions, or smart pointers
Redone below to not use those things. :)
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
using namespace std;
int myCompare (const void * a, const void * b)
{
if ((*(string *) a) < *(string *) b) return -1;
if ((*(string *) a) > *(string *) b) return 1;
return 0;
}
int main()
{
// Declare Variables
int userChoice = 0;
int numItems = 0;
cout << "How many items will be on your myList? ";
cin >> numItems;
cin.ignore ();
string *myList = new string[numItems];
while (true)
{
// Give the user some options
cout << "1. Add Item" << endl;
cout << "2. Remove Item" << endl;
cout << "3. Sort Items" << endl;
cout << "4. Exit" << endl;
cout << "Enter the number of the operation you wish to perform: ";
cin >> userChoice;
cin.ignore ();
cout << endl;
// Perform the operation
switch(userChoice)
{
case 1:
{
for(int i = 0; i < numItems; i++)
{
cout << "Item #" << i + 1 << " --> ";
getline(cin, myList [i]);
}
}
break;
case 2:
{
}
break;
case 3:
{
qsort (myList, numItems, sizeof (string *), myCompare);
}
break;
case 4:
{
delete [] myList;
return 0;
}
default:
{
cout << "Error! Invalid Selection" << endl;
}
}
// Output the myList
cout << "-------Items-------" << endl;
for(int i = 0; i < numItems; i++)
cout << myList [i] << endl;
} // end of while
}

The for loop isn't skipping the first element. The first element is just a an empty line.
Because the following clears the error flags.
cin.clear(); // Remove new line from cin --> No!!!!
If you want to skip until the new line you have to use ignore() instead.
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // this removes until newline from cin !

Related

Trying to incorporate void functions into switch statements

I'm a novice coding student and trying to create a menu using structs, functions, and switch statements to make a mini database for a class assignment. I'm trying to implant the functions into the switch statements.
I'm getting errors on lines 87 and 137 and I'm not sure where I'm going wrong. Any help, explanation, or correction is much appreciated.
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
using namespace std;
// Jaret Clark
// Week 3 Interactive Assignment
// INT 499
// Prof. Joseph Issa
// 03/31/2022
struct EZTechMovie {
string name;
string *cast[10];
string rating;
};
void displaymovie(EZTechMovie movie, int cast_num) {
int i;
cout << endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << endl;
cout << "Your entry:\n";
//Movies
cout << endl;
cout << "Movie TITLE: " << movie.name;
cout << endl;
//Movie rating
cout << "Movie Rating: " << movie.rating;
cout << endl;
//Cast name
cout << "Main Cast Members: \n";
//loop for cast members ~ stores in array
for (int i = 0; i < cast_num; ++i) {
cout << movie.cast[i];
cout << endl;
}
}
void mainmenu() {
string movie_input;
int m;
cout << endl;
cout << "Would you like to store movies into database? (yes or no) ";
getline(cin, movie_input);
cout << endl;
if (movie_input == "yes") {
string cont;
string cast_name;
int x, m, n, i, cast_num;
EZTechMovie moviedb[100];
cout << endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << endl;
for (n = 0; n < 100; n++) {
cout << "Movie Title: ";
getline(cin, moviedb[n].name);
cout << endl;
cout << "Movie rating: ";
getline(cin, moviedb[n].rating);
cout << endl;
cout << "How many cast do you want to enter? ";
cin >> cast_num;
cout << endl;
cin.ignore();
for (i = 0; i < cast_num; i++) {
cout << "Cast name: First and Last name: ";
getline(cin, moviedb[n].cast[i]);
cout << endl;
}
cout << endl;
displaymovie(moviedb[n], cast_num);
cout << endl;
cout << "Add more movies? (yes or no) ";
getline(cin, cont);
if (cont == "no") {
break;
}
cout << endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << endl;
}
}
else if (movie_input == "no") {
return;
}
else {
cout << "INVALID Input";
mainmenu();
}
}
// menu
void movieMenu() {
int choice;
EZTechMovie movie;
do {
cout << "***********************Welcome to EZTechMovie Movie Entry Menu***********************" << endl;
cout << "Press 1 to Enter Movie Info - Name, Cast Members, and Rating.\n";
cout << "Press 2 to Retrieve movie info recently entered.\n";
cout << "Press 3 To Quit program.\n";
// evaluate menu options in switch case
switch (choice) {
case 1:
mainmenu();
break;
case 2:
displaymovie(EZTechMovie movie, int cast_num);
break;
case 3:
cout << "Thank you and Goodbye!";
break;
default:
cout: "Invalid Selection. Try again!\n";
}
//get menu selection
cin >> choice;
} while (choice != 3);
}
int main() {
movieMenu();
}
Regarding the error on line 87 (getline(cin, moviedb[n].cast[i]);) :
moviedb[n].cast[i] is a std::string*, not std::string like you might have meant.
A quick compilation fix would be to use:
getline(cin, *(moviedb[n].cast[i]));
i.e. dereference the pointer.
However - this code raises other design/programming issues:
Why do you use std::string* and not std::string in the first place.
Why do you use C style array instead of std::vector (or std::array if you can commit to the size). This is relevant for both: string *cast[10]; and EZTechMovie moviedb[100];

C++ Switch Statment Exception Handling

I am trying to code exception handling in my switch statement for a memnu in case user inputs something other than an int. Tried many different methods and still get continuous loop when user inputs a character.
I have tried using std exception but even with the include my compiler still sees error during build.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>
using namespace std;
class Exam
{
public:
int loadExam()
{
//ifstream infile;
//string examName = exam;
ifstream infile("exam.txt");
streambuf *cinbuf = cin.rdbuf(); //save old buf
cin.rdbuf(infile.rdbuf()); //redirect std::cin to infile.txt!
string line, theQuestion, questiontype, theAnswer;
int questionvalue;
//get the number of questions from the first line in the file
getline(cin,line);
numquestions = atoi(line.c_str());
for(int count = 0; count < numquestions; count++){
getline(cin,line);
//get the next line with the question type and the value of the question
int npos = line.size();
int prev_pos = 0;
int pos = 0;
while(line[pos]!=' ')
pos++;
questiontype = line.substr(prev_pos, pos-prev_pos);
prev_pos = ++pos;
questionvalue = atoi(line.substr(prev_pos, npos-prev_pos).c_str()); // Last word
//process a true/false question
if (questiontype == "TF")
{
myQuestions[count] = new QuestionTF;
getline(cin,theQuestion);
myQuestions[count]->setQuestion(theQuestion,questionvalue);
}
//process a multiple choice question
if (questiontype == "MC")
{
myQuestions[count] = new QuestionMC;
getline(cin,theQuestion);
myQuestions[count]->setQuestion(theQuestion,questionvalue);
}
}
cin.rdbuf(cinbuf); //restore cin to standard input
return numquestions;
}
void displayExamQuestions(int numquestions)
{
string qtype;
//print out the questions that have been processed
for(int count = 0; count<numquestions;count++)
{
qtype = myQuestions[count]->getQuestionType();
cout << qtype << " " << myQuestions[count]->getValue() << "\n";
myQuestions[count]->printOptions();
cout << "\n";
}
}
private:
Question *myQuestions[10];
int numquestions;
};
int main() {
Exam myExam;
int numquestions;
int choice;
while((choice = displayMenu())!=3)
switch(choice)
{
case 1:
numquestions = myExam.loadExam();
break;
case 2:
myExam.displayExamQuestions(numquestions);
break;
default:
cout << "Invalid choice. Try again.\n\n";
}
getchar();
return 0;
}
int displayMenu()
{
int choice;
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam "<<endl;
cout << "\t2. Display Exam "<<endl;
cout << "\t3. Quit"<<endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
cin >> choice;
cout << "\n" << endl;
return choice;
}
Require output to read "Invalid selection, Please try again" when a user inputs a character or string of alpha characters.
In this case, validation should be handled by the displayMenu function for two reasons.
The displayMenu function says that it will return an integer so it should be responsible for ensuring the user inputs a number, not a char or string.
The displayMenu lists the options so it knows how many options are available, meaning it should also check that the integer is between 1 and 3.
Infinite loop with cin when typing string while a number is expected
int displayMenu() //This function should be responsible for validating that an
// int was inputed
{
int choice;
while (true)
{
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam " << endl;
cout << "\t2. Display Exam " << endl;
cout << "\t3. Quit" << endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
cin >> choice;
cout << "\n" << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n'); //This clears out the stream if they entered a string
//Try using cin.ignore() and inputing a string to see what happens.
}
else if (choice >= 1 && choice <= 3)
{
break;
}
}
return choice;
}
You could decouple this second part by having a displayMenu function that simply prints the menu and a second function called getInput that doesn't care what integer is inputed. It would then be up to the calling function to make sure the value is between 1 and 3.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>
using namespace std;
void displayMenu();
int getInput();
int main() {
int numquestions;
int choice = 0;
while (choice != 3)
{
displayMenu();
while ((choice = getInput()) < 1 || choice > 3)
{
std::cout << "Please pick a value between 1 and 3\n";
displayMenu();
}
switch (choice)
{
case 1:
cout << "Case 1\n";
break;
case 2:
cout << "Case 2\n";
break;
default:
cout << "Invalid choice. Try again.\n\n";
}
}
getchar();
return 0;
}
//Only responsible for getting an int
int getInput()
{
int choice;
while (true)
{
cin >> choice;
cout << "\n" << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
std::cout << "Please enter a valid number\n";
}
else
{
break;
}
}
return choice;
}
//This function only displays a menu
void displayMenu()
{
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam " << endl;
cout << "\t2. Display Exam " << endl;
cout << "\t3. Quit" << endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
}

Unable to solve the probelm

In the adding user section in the code below, I am unable to type any characters for the "Add another person?(y/n): " question. it just jumps back to entering age. How do I fix this?
I've tried to change ans into a string, implement a while loop to force the question to show up, and many other things. It just seems that nothing works and I've been trying it for the good part of two hours
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
int main()
{
char ans;
int people;
int option;
int count = 0;
struct data
{
string name;
int age;
char gender;
string comments;
}person[100];
// homescreen
homescreen:
cout << "Welcome to the Data Base!" << endl;
cout << endl;
// displaying all people
for (int list = 0; list < count; list++)
{
cout << list << ".) " << person[list].name << endl;
}
cout << endl;
cout << "[1] View Person" << endl;
cout << "[2] Add Person" << endl;
cout << "[3] Edit Person" << endl;
cout << "[4] Delete Person" << endl;
cout << "[5] Exit" << endl;
cout << "Choose Option: "; cin >> option;
// using options
while (option != 5)
{
if (option == 1)
{
view:
for (int list2 = 0; list2 < count; list2++)
{
cout << list2 << ".) " << person[list2].name << endl;
}
cout << endl;
cout << "Enter number of person you want: "; cin >> people;
system("cls");
cout << "Name: " << person[count].name << endl;
cout << "Age: " << person[count].age << endl;
cout << "Gender: " << person[count].gender << endl;
cout << "Comments: " << person[count].comments << endl << endl;
cout << "View another person?(y/n): "; cin >> ans;
if (ans == 'y')
{
system("cls"); goto view;
}
else if (ans == 'n')
{
system("cls"); goto homescreen;
}
}
if (option == 2)
{
add:
system("cls");
cout << "Name: "; cin >> person[count].name;
system("cls");
cout << "Age: "; cin >> person[count].age;
system("cls");
cout << "Gender(M/F/H): "; cin >> person[count].gender;
system("cls");
cout << "Comments: "; cin >> person[count].comments;
count++;
system("cls");
cout << "Add another person?(y/n): "; cin >> ans;
if (ans == 'y')
{
system("cls");
goto add;
}
else if (ans == 'n')
{
system("cls");
goto homescreen;
}
}
}
}
If you anybody can help me I'd be grateful
The goto statements in your code makes the program really good
spaghetti
structure and that is not
good.
Therefore, think instead of goto other options, such as infinite
while loop which will break once the user enters the n or moving
the code to the function.
Secondly what if you have not entered any persons and choosing the
option 1. You still output the attributes of the person as
count is initialized zero at least. Remember the attributes are
not initialized at this point. Accessing the uninitialized
variables will invoke undefined
behavior. Therefore,
provide a check (something like if(count > 0) )before you execute the code in option 1.
In addition to that, remember that
std::endl flushes the output buffer, and '\n' doesn't. Therefore, most of
the cases you might wanna use just
\n.
Last but not the least, use std::vector instead of the using C style arrays with some predefined size. What if the user has more than 100 inputs? The solution in C++ is std::vector, which can expand dynamically as its storage is handled automatically.
Following is a possible solution to your program, in which the comments will guide you through to the things that I mentioned above.
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
struct Data
{
std::string name;
int age;
char gender;
std::string comments;
Data(const std::string& n, int a, char g, const std::string& c) // provide a Constructor
:name(n), age(a), gender(g), comments(c)
{}
};
void debugMsg(const std::string& msg)
{
system("cls");
std::cout << "\n\n\t\t" << msg << "\n\n";
Sleep(3000);
}
int main()
{
std::vector<Data> person; // use std::vector to store the datas
while (true) // loop: 1
{
system("cls");
std::cout << "Welcome to the Data Base! \n\n";
std::cout << "[1] View Person\n";
std::cout << "[2] Add Person\n";
std::cout << "[3] Edit Person\n";
std::cout << "[4] Delete Person\n";
std::cout << "[5] Exit\n";
std::cout << "Choose Option: ";
int option; std::cin >> option;
switch (option) // use switch to validate the options
{
case 1:
{
while (true) // loop - 2 -> case 1
{
// if no data available to show -> just break the loop 2 and return to the outer loop(i.e, loop 1)
if (person.empty()) { debugMsg("No person available to show ....going to main manu...."); break; }
// otherwise: displaying all people
for (std::size_t index = 0; index < person.size(); ++index)
std::cout << index << ".) " << person[index].name << "\n";
std::cout << "\nEnter number of person you want: ";
std::size_t index; std::cin >> index;
// if the index is not valid -> just break the loop 2 and return to the outer loop(i.e, loop 1)
if (index < 0 || index >= person.size()) { debugMsg("Sorry, wrong index!... returning to the main menu......"); break; }
system("cls");
std::cout << "Name: " << person[index].name << std::endl;
std::cout << "Age: " << person[index].age << std::endl;
std::cout << "Gender: " << person[index].gender << std::endl;
std::cout << "Comments: " << person[index].comments << std::endl << std::endl;
std::cout << "View another person?(y/n): ";
char ans; std::cin >> ans;
if (ans == 'y') { system("cls"); continue; } // just continue looping
else if (ans == 'n') { break; } // this will break the loop 2 and return to the outer loop(i.e, loop 1)
else { debugMsg("Sorry, wrong option!... returning to the main menu......"); break; }
}
} break;
case 2:
{
while (true) // loop - 3 -> case 2
{
system("cls");
std::string name, comments; int age; char gender;
std::cout << "Name: "; std::cin >> name;
std::cout << "Age: "; std::cin >> age;
std::cout << "Gender(M/F/H): "; std::cin >> gender;
std::cout << "Comments: "; std::cin >> comments;
// simply construct the Data in person vector in place
person.emplace_back(name, age, gender, comments);
std::cout << "\n\nAdd another person?(y/n): ";
char ans; std::cin >> ans;
if (ans == 'y') { system("cls"); continue; }
else if (ans == 'n') { system("cls"); break; } // same as case 1
else { debugMsg("Sorry, wrong option!... returning to the main menu......"); break; }
}
} break;
case 3: { /*code*/ debugMsg("Sorry, Not implemented!... returning to the main menu......"); } break;
case 4: { /*code*/ debugMsg("Sorry, Not implemented!... returning to the main menu......"); } break;
case 5: return 0; // if its 5, just retun the main
default: break;
}
}
return 0;
}
As mentioned above, using "goto" is a bad style, so i would suggest structure your program a little. Below is my version.
Naturally, I did not add any checks and controls, the author will be able to do this on his own. But main logics should work. And, of course, it is better to use vector instead of static array.
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
enum options { OPT_VIEW = 1, OPT_ADD = 2, OPT_EDIT = 3, OPT_DELETE = 4, OPT_EXIT = 5 };
struct data
{
string name;
int age;
char gender;
string comments;
};
class App
{
private:
data person[100];
int count = 0;
public:
App();
void Run();
int HomeScreen();
void View();
void Add();
};
App::App() : count(0)
{}
void App::Run()
{
int option = HomeScreen();
while(option != OPT_EXIT)
{
switch(option)
{
case OPT_VIEW:
View();
break;
case OPT_ADD:
Add();
break;
}
option = HomeScreen();
}
}
int App::HomeScreen()
{
int option = 0;
cout << "Welcome to the Data Base!" << endl;
cout << endl;
// displaying all people
for(int list = 0; list < count; list++)
{
cout << list << ".) " << person[list].name << endl;
}
cout << endl;
cout << "[1] View Person" << endl;
cout << "[2] Add Person" << endl;
cout << "[3] Edit Person" << endl;
cout << "[4] Delete Person" << endl;
cout << "[5] Exit" << endl;
cout << "Choose Option: "; cin >> option;
return option;
}
void App::View()
{
char ans = 0;
do
{
int people = 0;
for(int list2 = 0; list2 < count; list2++)
{
cout << list2 << ".) " << person[list2].name << endl;
}
cout << endl;
cout << "Enter number of person you want: "; cin >> people;
system("cls");
cout << "Name: " << person[people].name << endl;
cout << "Age: " << person[people].age << endl;
cout << "Gender: " << person[people].gender << endl;
cout << "Comments: " << person[people].comments << endl << endl;
cout << "View another person?(y/n): "; cin >> ans;
}
while(ans == 'y');
system("cls");
}
void App::Add()
{
char ans = 0;
do
{
system("cls");
cout << "Name: "; cin >> person[count].name;
system("cls");
cout << "Age: "; cin >> person[count].age;
system("cls");
cout << "Gender(M/F/H): "; cin >> person[count].gender;
system("cls");
cout << "Comments: "; cin >> person[count].comments;
count++;
system("cls");
cout << "Add another person?(y/n): "; cin >> ans;
}
while(ans == 'y');
system("cls");
}
int main()
{
App program;
program.Run();
}

C++ Pulling information and looping to display

Not under standing looping for arrays. Looping through all of grab some or search. Can someone explain the process? Thanks in advance. Sorry if duplicate. I looked around and couldnt find a solid explaination that I could understand.
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void allContacts(string names[], string phones[])
{
cout << "Showing all contacts... Press Q to go back to main menu" << endl;
}
void addName(string names[], string phones[])
{
bool keepGoing;
string input;
beginning:
for (int i = 0; i < sizeof(names); i++)
{
cout << "Enter contact name: ";
cin >> names[i];
cout << "Enter contact number: ";
cin >> phones[i];
cout << "Do you have another contact to add? y or no" << endl;
cin >> input;
if(input == "y" || input == "Y")
{
goto beginning;
}
if(input == "n" || input == "N")
{
cout << "Contacts you have entered: " << endl;
cout << names[i] << " : " << phones[i] << endl;
}
}
}
void searchName(string names[], string phones[])
{
string name;
cout << "Enter Name: ";
cin >> name;
cout << "Search for a name or Press Q to go back to main menu" << endl;
for (int i = 0; i < sizeof(names); i++){
if (name == names[i])
{
cout << counter << names[i] << " 's phone number is: " << phones[i] << endl;
} else {
cout << "No results found";
}
}
}
int main()
{
string names[100];
string phones[100];
int choice;
cout << "============================" << endl;
cout << "=== Welcome to PhoneBook ===" << endl;
cout << "============================" << endl;
cout << "1- Add a New Contact" << endl;
cout << "2- Search By Name" << endl;
cout << "3- Display All" << endl;
cout << "0- Exit" << endl;
cout << "Select a number: " << endl;
cin >> choice;
switch(choice)
{
case 1:
addName(names, phones);
break;
case 2:
searchName(names, phones);
break;
case 3:
allContacts(names, phones);
break;
case 0:
cout << "Exiting PhoneBook...";
break;
}
}
In C++ arrays lose attributes when passed to functions. Those attributes are capacity and size (number of filled slots). You will need to pass this additional information for each array:
void addName(string names[], unsigned int names_capacity, unsigned int names_size,
string phones[], unsigned int phones_capacity, unsigned int phones_size)
To get around this, you can use std::vector. The std::vector knows its capacity and size, so you don't have to pass additional attributes to your function.
Also, if you use tolower or toupper before you compare, you only need to make one comparison:
char input;
cout << "Do you have another contact to add? y or n" << endl;
cin >> input;
input = toupper(input);
if(input == 'Y')
When using strings, you can convert them to all uppercase or all lowercase by using std::transform, such as:
std::transform(input.begin(),
input.begin(), input.end(),
tolower);

How can i change the value of an array then display the whole new array?

i need help. I have an array of 10, and it consists of a string and a value initialized to it. My question is how i can ask the user to input how much more to add or how much to remove. then display the updated list.
for example choose valve, then add 2 more, which will make it 12, then display the updated array with the other arrays. i need to pass it through a function also. please and thank you for the help in advance, here it my code so far. Feel free to criticize as much as you guys would like. It will only help me get better :)
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
#include <cstring>
#include <string>
using namespace std;
//define Structure as invParts
struct invParts{
string name;
int qty;
};
void addparts(invParts *&c,int);
void removeparts(invParts *&c, int);
int main()
{
invParts *descrip;
int row = 0;
char choice;
invParts bin[10]= { {"valve",10}, {"Bearing",5}, {"Bushing",21},
{"Coupling",7}, {"Flange",5}, {"Gear",5},
{"Gear House", 5}, {"Vacuum Gripper", 25},
{"Cable",18}, {"Rod",12}, };
cout<<"-----------------------------------------------------" << endl;
cout<<"Part Description" << " " << "Number of parts in the bin" << endl;
cout <<"----------------------------------------------------" << endl;
cout << endl;
for(row = 0; row < 10; row++)
{
cout << setw(11)<< left <<bin[row].name << setw(25) << right << bin[row].qty<< endl;
}
cout << endl;
cout << "Here are 3 options" << endl;
cout << "Type A , to Add parts" << endl;
cout << "Type R , to Remove parts" << endl;
cout << "Type E, to Exit Program" << endl;
cout << "Choose your option: ";
cin >> choice;
cout << endl;
switch (choice)
{
int num;
case 'A' :
case 'a' : cout <<"You will now add" << endl;
addparts(descrip,num);
break;
case 'R':
case 'r': cout <<"You will now remove" << endl;
//removeparts(descrip,num);
break;
case 'E':
case 'e': cout<<"Now exiting program" << endl;
exit(0);
}
system("pause");
return 0;
}
void addparts(invParts *&c,int number)
{
string what;
int n;
cout <<"Which part? " << endl;
cin >> what;
//am i doing this right?
if ( what == "valve" || what == "Valve")
cout <<"How much do you want to add? "<<endl;
cin >> n;
}
/*void removeparts(invParts *&c, int)
{
//you guys can show me how to do the add, i can do the remove
}
*/
You are using the wrong data structure to capture the inventory. You need something like
typedef std::map<std::string, int> Inventory;
Here's an updated version of your program.
#include <iostream>
#include <string>
#include <iomanip>
#include <map>
using namespace std;
typedef std::map<std::string, int> Inventory;
void initializeInventory(Inventory& inv);
void displayInventory(Inventory const& inv);
void addparts(Inventory& inv);
void removeparts(Inventory& inv);
int main()
{
Inventory inv;
char choice;
initializeInventory(inv);
displayInventory(inv);
while ( true )
{
cout << "Here are 3 options" << endl;
cout << "Type A , to Add parts" << endl;
cout << "Type R , to Remove parts" << endl;
cout << "Type E, to Exit Program" << endl;
cout << "Choose your option: ";
cin >> choice;
cout << endl;
switch (choice)
{
case 'A' :
case 'a' : cout <<"You will now add" << endl;
addparts(inv);
break;
case 'R':
case 'r': cout <<"You will now remove" << endl;
//removeparts(inv);
break;
case 'E':
case 'e': cout<<"Now exiting program" << endl;
exit(0);
}
displayInventory(inv);
}
return 0;
}
void initializeInventory(Inventory& inv)
{
inv["Valve"] = 10;
inv["Bearing"] = 5;
inv["Bushing"] = 21;
inv["Coupling"] = 7;
inv["Flange"] = 5;
inv["Gear"] = 5;
inv["Gear House"] = 5;
inv["Vacuum Gripper"] = 25;
inv["Cable"] = 18;
inv["Rod"] = 12;
}
void displayInventory(Inventory const& inv)
{
cout<<"-----------------------------------------------------" << endl;
cout<<"Part Description" << " " << "Number of parts in the bin" << endl;
cout <<"----------------------------------------------------" << endl;
cout << endl;
for (auto item : inv )
{
cout << setw(15) << left << item.first << setw(25) << right << item.second << endl;
}
cout << endl;
}
void addparts(Inventory& inv)
{
string what;
int n;
cout <<"Which part? " << endl;
cin >> what;
//am i doing this right?
Inventory::iterator iter = inv.find(what);
if ( iter == inv.end() )
{
cout << "There is no such part in the inventory.\n";
return;
}
cout <<"How much do you want to add? "<<endl;
cin >> n;
iter->second += n;
}
void removeparts(Inventory& inv)
{
// ????
}
Update
The inventory can be initialized using:
Inventory inv = { {"Valve",10}, {"Bearing",5}, {"Bushing",21},
{"Coupling",7}, {"Flange",5}, {"Gear",5},
{"Gear House", 5}, {"Vacuum Gripper", 25},
{"Cable",18}, {"Rod",12} };
There is no need for a separate function to initialize the inventory.