c++ program crashing. Not sure why - c++

Your Community Supported Agriculture (CSA) farm delivers a box of fresh fruits and vegetables to your house once a week. For this programming project, define the class BoxOfProduce that contains exactly three bundles of fruits or vegetables. You can represent the fruits or vegetables as an array of type string. Add appropriate constructors and accessor/mutator functions to get or set the fruits or vegetables stored in the array. Also write an output
function that displays the complete contents of the box on the console.
Next, write a main function that creates a BoxOfProduce with three items randomly selected from this list:
• Broccoli
• Tomato
• Kiwi
• Kale
• Tomatillo
Do not worry if your program randomly selects duplicate produce for the three items. Next, the main function should display the contents of the box and allow the user to substitute any one of the five possible fruits or vegetables for any of the fruits or vegetables selected for the box. After the user is done with substitutions it should output the final contents of the box to be delivered. Then it should ask if the user wants to create another box and if
yes, it should repeat the above steps. It should keep doing so until the user chooses not to create another box of produce.
Finally, add a static variable to your class that keeps track of the total number of boxes of produce created and a static function that returns that value. Display this value in the main function at the end of each iteration of the main loop.
My program gets to the removeStuff() function after the user types Y if they want to swap out the bundle. Once it gets there and the user types what fruit/vegetable they want to remove, the program shuts down. I'm not sure why this is happening. Any help is greatly appreciated.
#include <iostream>
#include "BoxOfProduce.h"
#include <string>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <memory>
#include <algorithm>
using namespace std;
int main()
{
char myChar;
string answer = "";
srand(time(0));
BoxOfProduce bo;
bo.randomize();
cout << "Your box initially starts with: " << endl;
cout << bo.random << endl;
vector<string> randomResult = bo.randomize();
for (vector<string>::const_iterator iter = randomResult.begin(), iterEnd = randomResult.end();
iter != iterEnd; ++iter){
cout << *iter << endl;
}
cout << "Would you like to swap out any of your bundles for any of the five bundles you didn't get? (Y/n) " << endl;
getline(cin, answer);
if(answer.length() == 1){
myChar = answer[0];
}
if(myChar == 'y' || myChar == 'Y'){
cout << "Okay!" << endl;
bo.removeStuff();
}else if(myChar == 'n' || myChar == 'N'){
BoxOfProduce bo1;
bo1.createBox();
}else{
cout << "That is not a valid character. Goodbye." << endl;
return 0;
}
}
---------------------------------------------------------------------
#include "BoxOfProduce.h"
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <memory>
#include <algorithm>
using namespace std;
BoxOfProduce::BoxOfProduce()
{
}
vector<string> BoxOfProduce::randomize()
{
srand(time(0));
string choices[] = {"Broccoli", "Tomato", "Kiwi", "Kale", "Tomatillo"};
vector<string> random;
for(int i = 0; i < 3; i++)
{
random.push_back(choices[rand() % 5]);
}
return random;
}
vector<string> BoxOfProduce::printContents(vector<string> bundles[3])
{
cout << "Your box contains these three bundles: " << endl;
cout << bundles << endl;
}
void BoxOfProduce::createBox(){
cout << "Would you like to create another box? (Y/n)" << endl;
getline(cin, answer);
if(answer.length() == 1){
myChar = answer[0];
if(myChar == 'y' || myChar == 'Y'){
vector<string> printContents();
randomize();
}
}
}
void BoxOfProduce::removeStuff()
{
cout << "Of your three bundles, what would like to remove?" << endl;
cin >> answer;
vector<string>::iterator result = find(randomResult.begin(), randomResult.end(), answer);
if(answer == "Tomato" || answer == "tomato" || answer == "broccoli" || answer == "Broccoli" || answer == "kiwi" || answer == "Kiwi" || answer == "kale" || answer == "Kale" || answer == "tomatillo" || answer == "Tomatillo"){
randomResult.erase(result);
bundles[3] = randomResult;
addStuff();
}else{
cout << "That is not a choice!" << endl;
}
}
void BoxOfProduce::addStuff()
{
cout << "Now that we have removed a bundle, what would you like to swap that out for: Tomato, Broccoli, Kiwi, Kale, or Tomatillo?" << endl;
getline(cin, answer);
if(answer == "Tomato" || answer == "tomato" || answer == "broccoli" || answer == "Broccoli" || answer == "kiwi" || answer == "Kiwi" || answer == "kale" || answer == "Kale" || answer == "tomatillo" || answer == "Tomatillo"){
randomResult.push_back(answer);
bundles[3] = randomResult;
printContents(bundles);
}else{
cout << "Sorry, you can't add that." << endl;
}
}
-----------------------------------------------------------------
#ifndef BOXOFPRODUCE_H
#define BOXOFPRODUCE_H
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class BoxOfProduce
{
public:
BoxOfProduce();
string getBundles();
void setBundles(string b);
vector<string> randomize();
string bundleOfFruit();
vector<string> printContents(vector<string> bundles[3]);
string random;
void createBox();
void removeStuff();
void addStuff();
private:
vector<string> bundles[3];
vector<string> choices[5];
char myChar;
string answer = "";
vector<string> randomResult;
};
#endif // BOXOFPRODUCE_H
This is still very much a work in progress, so please go easy on me.

You are accessing out of bounds, e.g.
bundles[3] = randomResult;
as you have the declaration
vector<string> bundles[3]; // 3 elements, last one is indexed by 2
and in C or C++ the indexing starts from 0, so the last element of the array bundles should be bundles[2].
In any case, are you sure you need an array of vector of strings? It seems a bit odd.

Related

C++ Loop for String

I am struggling to create a loop for getting input from user. The input must push_back() each instance.
#include <iostream>
#include <array>
#include <cstring>
#include <vector>
#include <string>
#include <string.h>
using namespace std;
int main()
{
vector <string> bookQ = { "what","book","is","that","you","are","reading" };
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
string input;
int x = 0;
for (x != '1') { // require a loop to input string and end when user prompts
cout << "Enter 1 to stop" << endl; //
cin >> x; //
getline(cin, input); //
bookQ.push_back(input); //
} //
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}
Your for loop is missing the declaration and (iteration) expression parts:
for (declaration-or-expression; declaration-or-expression; expression)
so it should have looked like this:
for (;x != '1';) {
which is generally written as
while (x != '1') {
That would cause problems though since it would not stop directly when the user entered 1.
You are also comparing an int with a char ('1'), so in order to exit the loop, the user would have had to enter 49 (the ASCII value for 1), not 1.
You are also mixing formatted input (cin >> x) with unformatted input (getline). I suggest that you stick to one only.
Example:
while(cout << "Enter 1 to stop\n", getline(cin, input) && input != "1") {
bookQ.push_back(input);
}
Assuming you meant that input is a string, then you've made a few mistakes with types. First of all, you've used wrong type for variable x, you used int which is integer type, and the type string is required. Secondly, when comparing x with '1' you used single quotes, which define the type of variable as char, not string. To make 1 a string you should use double quotes, like so "1". Besides that, you have used for(condition), which is incorrect syntax. You should use while(condition). Also, when your loop iterates, the x variable is the input book name, and input variable is always an empty string, so I would suggest replace input with x everywhere. The working code is below.
P.S. I am not sure whether you want "1" to be in the final vector, so I haven't changed that
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<string> bookQ = {"what", "book", "is", "that", "you", "are", "reading"};
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
string input;
string x;
while (x != "1") {
cout << "Enter 1 to stop" << endl;
cin >> x;
bookQ.push_back(x);
}
for (int i = 0; i < bookQ.size(); i++) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}
simply check if input is 1 everytime the user enters somthing, and when it does = 1, simply break loop.
string x;
while (true) { // require a loop to input string and end when user prompts
cout << "Enter 1 to stop" << endl;
cin >> x;
if (x == "1"){
break;
}
getline(cin, x);
bookQ.push_back(x);
}
}
First, your for syntax is wrong. You want a while loop instead, or in this case a do..while loop would make more sense. Also, you are pushing the user's input into the vector before validating what the input actually is.
Second, x is an integer, but '1' is a character whose ASCII value is number 49. Your loop will never end, because != will always be true. Since you want the user to enter number 1 to stop the loop, you need to drop the quotes:
Third, what is the point of pre-populating bookQ? Just declare the bookQ without any initial data, and then cout the entire question as a normal string. This way, after the user is done entering input, the vector will contain only the user's input and nothing else.
Try something more like this:
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
vector <string> bookQ;
string input;
cout << "what book is that you are reading" << endl;
do {
cout << "Enter a book, or 1 to stop" << endl;
getline(cin >> ws, input);
if (input == "1") break;
bookQ.push_back(input);
}
while (true);
for (size_t i = 0; i < bookQ.size(); ++i) {
cout << bookQ[i] << ' ';
}
cout << endl;
return 0;
}

Is there a way to compare 2 elements of array of type char initialized with int?

I'm having a program to allow a user to enter 12 elements of type char initialized with the characters that form, eg "991231066245" and I would like to compare whether the 3rd element and 4 element is equal to 12.
For example:
char UserInput[20];
cout << "user input: ";
cin >> UserInput; //eg: 991231066245
//compare
int a = atoi(UserInput[2] + UserInput[3]); //something like this
if(a == 12){
cout << "yes";
}
But I able to get UserInput[0] & UserInput[1] by using UserInput[2]=\0
then user atoi(UserInput) to compare
If I add UserInput[4] = \0 then i will get 4 element so want to ask that is there any way to do? Thank you.
What about this:
if (UserInput[2] == '1' && UserInput[3] == '2')
{
std::cout << "yes\n";
}
If you have to convert to int, use std::string instead of char*, then it is very easy:
#include <iostream>
#include <string>
int main()
{
std::string UserInput{ "991231066245" };
int a{ std::stoi(UserInput.substr(2, 2)) };
std::cout << a << '\n';
return 0;
}
Output:
12

Accessing C++ Vector as number

So basically I am trying to have a list of games, and give the user the option to delete it. It looks something like this:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
//setup
vector<string> games;
games.push_back("Team Fortress 2");
games.push_back("Skyrim");
games.push_back("Portal");
vector<string>::iterator myIterator
//main
int delItem;
cin >> delItem; // Consumes a number to represent the game to be deleted
while (iter != games.end()) // Displays all the games
{
cout << j << ") " << *iter << endl;
iter++;
j++;
}
while ((delItem <= games.begin()) || (delItem > games.end())) // can only be 1, 2, or 3
{
cout << "\nThat input is incorrect. Please try again: ";
getline (cin, delItem);
}
myIterator = (games.begin() + (delItem - 1);
games.erase(myIterator); // Deletes the item
cout << "\nThe game has been deleted.";
return 0;
}
So when I display the list, it looks like this:
1) Team Fortress 2
2) Skyrim
3) Portal
A user can type the number preceding the game and that will be selected to delete it. What I am trying to do, is to prevent the user from enter a number higher or lower than those three numbers. I attempt this in the second while loop, but it looks like games.begin() is not a number. I know that this is probably a dumb mistake that I just barely missed, but any help would be great.
There are several problems with your code.
You are reading the user's input before you have even printed out the available options for the user to choose from. You need to reverse those operations.
You are using variables that have not been declared.
When the user enters an invalid number, you are calling std::getline() to get a new number, but std::getline() outputs to a std::string, not to an int.
Try something more like this instead:
#include <iostream>
#include <string>
#include <vector>
#include <limits>
using namespace std;
int main()
{
//setup
vector<string> games;
games.push_back("Team Fortress 2");
games.push_back("Skyrim");
games.push_back("Portal");
vector<string>::iterator myIterator;
//main
int j = 1;
for (myIterator = games.begin(); myIterator != games.end(); ++myIterator) // Displays all the games
{
cout << j << ") " << *myIterator << endl;
++j;
}
cout << "\nPick an item to delete: ";
int delItem;
do
{
if (cin >> delItem) // Consumes a number to represent the game to be deleted
{
if ((delItem >= 1) && (delItem <= games.size())) // can only be 1, 2, or 3
break;
}
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.clear();
cout << "\nThat input is incorrect. Please try again: ";
}
while (true);
/*
alternatively:
int delItem;
do
{
string line;
if (!getline(cin, line)) {
// error!
return 0;
}
istringstream iss(line);
if (iss >> delItem) // Consumes a number to represent the game to be deleted
{
if ((delItem >= 1) && (delItem <= games.size())) // can only be 1, 2, or 3
break;
}
cout << "\nThat input is incorrect. Please try again: ";
}
while (true);
*/
myIterator = games.begin() + (delItem - 1);
games.erase(myIterator); // Deletes the item
cout << "\nThe game has been deleted.";
return 0;
}
You are right that games.begin() is not a number. It's an iterator. However, you can use games.size() to determine the number of elements in the games vector. You can use this for the maximum number which the user can type. From what I can tell, the minimum number will always be the same. I leave it as an exercise for the reader to determine what it is.

Code keeps printing "1" when everything is correct

The code runs and all but it doesn't print out the vowels, but instead prints a "1".
#include <iostream>
#include <string>
using namespace std;
int countVowels(string sentence,int numVowels)
{
for(int i =0; i<sentence.length(); i++)
{
if((sentence[i]==('a'))||(sentence[i]==('e'))||(sentence[i]==('i'))||(sentence[i]==('o'))||(sentence[i]==('u'))||(sentence[i]==('A'))||(sentence[i]==('E'))||(sentence[i]==('I'))||(sentence[i]==('O'))||(sentence[i]==('U')))
numVowels=numVowels+1;
}
}
int main()
{
string sentence;
int numVowels = 0;
do{
cout << "Enter a sentence or q to quit: ";
cin >> ws;
getline(cin,sentence);
}
if(sentence == 'q'|| sentence == 'Q');
cout << "There are " << countVowels << " vowels in your sentence." << endl;
return 0;
}
The output should be like this:
Enter a sentence or a to quit: I like apples!
There are 4 vowels in your sentence, and 11 letters.
Enter a sentence or q to quit: q
Bye!
My problem:
Can someone explain to me why it keeps printing a "1", and my "if" statement where I am supposed to assign the hotkey "q" to exit the program isn't working. When I run the program I get an error at the if statement saying "no match for operators=="
I usually don't like just providing a full solution, but since your question shows you have made a good effort, here's how I would write it (well, not quite, I simplified a little to be more beginner friendly):
#include <algorithm>
#include <iostream>
#include <string>
bool isVowel(char c)
{
// A simple function that returns true if the character passed in matches
// any of the list of vowels, and returns false on any other input.
if ( 'a' == c ||
'e' == c ||
'i' == c ||
'o' == c ||
'u' == c ||
'A' == c ||
'E' == c ||
'I' == c ||
'O' == c ||
'U' == c) {
return true; // return true if it's a vowel
}
return false; // remember to return false if it isn't
}
std::size_t countVowels(std::string const& sentence)
{
// Use the standard count_if algorithm to loop over the string and count
// all characters that the predicate returns true for.
// Note that we return the resulting total.
return std::count_if(std::begin(sentence),
std::end (sentence),
isVowel);
}
int main() {
std::string sentence;
std::cout << "Please enter a sentence, or q to quit: ";
std::getline(std::cin, sentence);
if ( "q" == sentence ||
"Q" == sentence) {
// Quit if the user entered a string containing just a single letter q.
// Note we compare against a string literal, not a single character.
return 0;
}
// Call the counting function and print the result.
std::cout << "There are "
<< countVowels(sentence) // Call the function on the input.
<< " vowels in your sentence\n";
return 0;
}
Hopefully the comments make it all clear.
Now you might have been told that you can't use the standard algorithms (std::count_if), since part of the exercise seems to be to write that. Well I'll leave that to you. Your current version is close to correct, but remember to return the result. And you don't really need to pass in the numVowels count, just create that within the function, and remember to return it.

while Statement breaking loop

I added a while statement around my code so that the user could repeat the process as my teacher instructed, the way I did it worked on other code but for some reason it broke this one I could use help making it work please and thank you. The point of the code is to just flip 10000 coins and output the number of heads and tails. Thanks for any and all help.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
// Keaton Graffis 12/22/2012
int coin()
{
int flip;
// assign random numbers
flip = rand() % 2 + 1;
return (flip);
}
int main()
{
char choice = 'y';
while (choice == 'y' || choice == 'Y');
{
double numFlips = 10000;
int count, face, heads = 0, tails = 0;
// initialize the random number generator
srand(static_cast<int>(time(0)));
// generate and count the number of heads and tails
for (int count = 1; count <= numFlips; count++)
{
face = coin();
if (face == 1)
heads++;
else
tails++;
}
cout << "The number flips: " << numFlips << endl;
cout << "The number of heads: " << heads << endl;
cout << "The number of tails: " << tails << endl;
// Asks user if they would like to go again(makes cod enot run, not sure why, this works on all my other code)
while (1)
{
cout << "Would you like to play again [Y]es or [N]o?\n";
cin >> choice;
if (choice == 'y' || choice == 'Y' || choice == 'n' || choice == 'N')
break;
}
}
}
Remove the semicolon after the while condition of the first loop. Only full statements are terminated by a ;.
Notes:
Since C++11, better facilities for random number generation are provided in the <random> header. Use these!