I've been working on a program recently that takes names as inputs and will eventually sort & binary search them. However upon attempting to make the array a dynamic size (that would increase by one with each loop iteration), it ran into various issues.
I can make the string array composed of 20 elements and the program works, but the extra credit for my assignment is to make it a dynamic size. Currently the program crashes without any sort of error code once it reaches "getline(cin, Names[x]);". I've been searching around and I know it'd be easier to do a vector instead of an array in this case, however I don't believe I'm allowed to use vectors on this assignment.
Thanks
Original Code
using namespace std;
#include <iostream>
#include <string>
void main()
{
int x = 0;
string * Names = new string[x];
bool NameInputEnd(0);
cout << " Enter your names to be sorted\n";
cout << "To exit just press [Enter] at any time\n";
do
{
cout << x << endl;
cout << "\n< Name " << (x + 1) << " > = ";
!!**CRASHES HERE**!!
getline(cin, Names[x]);
if (Names[x].empty() || x == 19)
{
cout << "\nFinal Name Amount = " << (x + 1) << endl << endl;
NameInputEnd = 1;
continue;
}
x++;
} while (NameInputEnd == 0);
delete [] Names;
}
Changes
int tempsize(1), x(0);
string * Names = new string[tempsize];
...
do
{
...
x++;
tempsize++;
}while (NameInputEnd == 0);
An array cannot be resized once it has been created. You have to destroy it and create a new array with a copy of the existing data. For example:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void main()
{
int x = 0;
int capacity = 20;
string * Names = new string[capacity];
string Name;
cout << " Enter your names to be sorted\n";
cout << "To exit just press [Enter] at any time\n";
do
{
cout << x << endl;
cout << "\n< Name " << (x + 1) << " > = ";
if ((!getline(cin, Name)) || Name.empty())
break;
if (x == capacity)
{
int newCapacity = capacity + 20;
string *newNames = new string[newCapacity];
copy(Names, Names + x, newNames);
delete [] Names;
Names = newNames;
capacity = newCapacity;
}
Names[x] = Name;
++x;
}
while (true);
cout << "\nFinal Name Amount = " << x << endl << endl;
delete [] Names;
}
You really should use a std::vector, though:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void main()
{
vector<string> Names;
string Name;
Names.reserve(20); // optional
cout << " Enter your names to be sorted\n";
cout << "To exit just press [Enter] at any time\n";
do
{
cout << Names.size() << endl;
cout << "\n< Name " << (Names.size() + 1) << " > = ";
if ((!getline(cin, Name)) || Name.empty())
break;
Names.push_back(Name);
}
while (true);
cout << "\nFinal Name Amount = " << Names.size() << endl << endl;
}
Related
Here's my current code:
#include <iostream>
#include <set>
using namespace std;
int main()
{
string numOne, numTwo, numThree;
int pointOne, pointTwo, pointThree, totalPoint;
set<string> ansOne = { "TOE", "TONGUE", "TOOTH" };
cout << "Give A Body Part That Starts With The Letter T";
cout << "\n1. ";
cin >> numOne;
if (ansOne.find(numOne) == ansOne.end())
{
ansOne.erase(numOne);
cout << "Wrong!";
pointOne = 0 + 0;
}
else
{
cout << "Nice, You got a Point!";
pointOne = 1 + 0;
}
cout << "\n2. ";
cin >> numTwo;
if (ansOne.find(numTwo) == ansOne.end())
{
ansOne.erase(numTwo);
cout << "Wrong!";
pointTwo = 0 + pointOne;
}
else
{
cout << "Nice, You got a Point!";
pointTwo = 1 + pointOne;
}
cout << "\n3. ";
cin >> numThree;
if (ansOne.find(numThree) == ansOne.end())
{
ansOne.erase(numThree);
cout << "Wrong!";
pointThree = 0 + pointTwo;
}
else
{
cout << "Nice, You got a Point!";
pointThree = 1 + pointTwo;
}
totalPoint = pointOne + pointTwo + pointThree;
cout << "\n" << totalPoint;
}
What I want to do is, if the answer is after they put the answers, and if the word is in there, I want to erase that word from the set so they can't duplicate the answer. But it's not getting erased from the set.
Per your declared logic, you put the erase in the wrong branch of the if, only erasing a word when the word wasn't in the set already, and not erasing it when it was. The first if/else block would be fixed with:
if (ansOne.find(numOne) == ansOne.end())
{
// Removed ansOne.erase(numOne); here, because you just confirmed it's not in ansOne
cout << "Wrong!";
pointOne = 0;
}
else
{
ansOne.erase(numOne); // It's in ansOne, remove it so it can't be guessed again
cout << "Nice, You got a Point!";
pointOne = 1;
}
Similar changes would be made to the other two if/else blocks.
Note that this code would be much simpler with a for loop that runs three times and maintains the running total, rather than individual variables for each of three nearly identical tests. For example, the fixed version of your code could simplify to:
int main()
{
string userinput; // Just one string for input
int totalPoints = 0; // Just one score counter
set<string> ansOne = { "TOE", "TONGUE", "TOOTH" };
cout << "Give A Body Part That Starts With The Letter T";
for (int i = 1; i <= 3; ++i) {
cout << '\n' << i << ". "; // Number prompts dynamically
cin >> userinput;
const auto inputloc = ansOne.find(userinput); // Storing off iterator speeds erasure later (admittedly not meaningful for three element set
if (inputloc == ansOne.end())
{
cout << "Wrong!";
}
else
{
ansOne.erase(inputloc); // Erase with iterator to element found
cout << "Nice, You got a Point!";
++totalPoints;
}
}
cout << '\n' << totalPoint << '\n';
}
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string getItemName(int k) {
if(k == 0) {
return "Sunkist Orange";
} else if(k == 1) {
return "Strawberry";
} else if(k == 2) {
return "papaya";
} else if(k == 3) {
return "Star Fruit";
} else if(k == 4) {
return "Kiwi";
}
return "";
}
int main() {
double prices[] = {2.00, 22.00, 5.00, 6.00, 10.00};
double total = 0.0;
string cart[50];
int key = 0;
int weight = 0;
int index = 0;
cout << "Welcome to Only Fresh Fruit Shop\n\nToday's fresh fruit <Price per Kg>\n";
cout << "0-Sunkist Orange RM2\n";
cout << "1-Strawberry RM22\n";
cout << "2-Papaya RM5\n";
cout << "3-Star Fruit RM6\n";
cout << "4-Kiwi RM10\n";
while (key != -1) {
double current = 0.0;
cout << "Enter fruit code <-1 to stop>: " << endl;
cin >> key;
if (key == -1) {
break;
}
cout << getItemName(key) << endl;
cout << "Enter weight <kg> : " << endl;
cin >> weight;
current = prices[key] + weight;
total = total + current;
}
cout << "-------------------------------------------------------\nReciept\n";
for(int i = 0; i < index; i++) {
cout << cart[i] << "\n";
}
cout << "TOTAL = RM" << total << endl;
return 0;
}
This is my code so far. The system have to display what fruit the user have chosen at in the receipt. My code is not working on the receipt part. Is there any other way on how to improvise the code to make it simpler? How can I improvise?
At very first you can re-organise your data better:
struct Product
{
std::string name;
double price;
};
This struct keeps the data closely related to a single product (fruit in this case) together locally.
You might organise these in an array (preferrably std::array, alternatively raw) making access to simpler – making your getItemName function obsolete entirely. Instead of a static array a std::vector would allow to manage your products dynamically (adding new ones, removing obsolete ones, ...).
You can even use this array to output your data (and here note that your condition in the while loop is redundant; if the inner check catches, the outer one cannot any more as you break before; if the inner one doesn't, the outer one won't either, so prefer a – seeming – endless loop):
std::vector<Product> products({ {"Apple", 2.0 }, { "Orange", 3.0 } });
for(;;)
{
std::cout << "Welcome ... \n";
for(auto i = products.begin(); i != products.end(); ++i)
{
std::cout << i - products.begin() << " - " << i->name
<< " RM " << i-> price << '\n';
}
// getting key, exiting on -1
if(0 <= key && key < products.size()
{
// only now get weight!
}
else
{
std::cout << "error: invalid product number" << std::endl;
}
}
Now for your cart you might just add indices into the vector or pointers to products – note, though, that these will invalidate if you modify the vector in the mean-time – if you do so you need to consider ways to correctly update the cart as well – alternatively you might just empty it. Inconvenient for the user, but easy to implement…
In any case, such a vector of pointers to products would easily allow to add arbitrary number of elements, not only 50 (at least as much as your hardware's memory can hold...) and would allow for simple deletion as well.
Calculating the full price then might occur only after the user has completed the cart:
// a map allows to hold the weights at the same time...
std::map<Product*, weight> cart;
for(;;)
{
// ...
if(0 <= key && key < products.size()
{
double weight;
std::cin >> weight;
// TODO: check for negative input!
// (always count with the dumbness of the user...)
cart[&products[key]] += weight;
// note: map's operator[] adds a new entry automatically,
// if not existing
}
}
Finally you might iterate over the cart, printing some information and calculating total price for the shopping cart:
double total = 0.0;
for(auto& entry : cart) // value type of a map always is a std::pair
{
std::cout << entry.first->name << "..." << entry.second << " kg\n";
total += entry.first->price * entry.second;
// note: you need MULTIPLICATION here, not
// addition as in your code!
}
std::cout << "Total price: RM " << total << std::endl;
This should do it whilst staying close to original code, I also improved you're method of gathering price/name a bit, try to catch the out of index exceptions or check if current index is NULL. Good luck!
#include <iostream>
#include <string>
#include <sstream>
#include <vector>;
using namespace std;
std::vector<std::string> itemList = {"Sunkist Orange", "Strawberry", "Papaya", "Star Fruit", "Kiwi"};
//If you dont want this to be global put it in the getItemName function
string getItemName(int k) {
return itemList.at(k);
}
int main() {
std::vector<double> prices = { 2.00, 22.00, 5.00, 6.00, 10.00 };
double total = 0.0;
int key = 0, weight = 0;
cout << "Welcome to Only Fresh Fruit Shop\n\nToday's fresh fruit <Price per Kg>\n";
cout << "0-Sunkist Orange RM2\n";
cout << "1-Strawberry RM22\n";
cout << "2-Papaya RM5\n";
cout << "3-Star Fruit RM6\n";
cout << "4-Kiwi RM10\n";
while (key != -1) {
double current = 0.0;
cout << "Enter fruit code <-1 to stop>: " << endl;
cin >> key;
if (key == -1) {
break;
}
cout << getItemName(key) << endl;
cout << "Enter weight <kg> : " << endl;
cin >> weight;
current += prices.at(key) + weight;
total += total + current;
cout << "-------------------------------------------------------\nReciept\n";
cout << "Purchased: " << getItemName(key) <<" "<< "TOTAL = RM" << total << "\n" << endl;
}
return 0;
}
I noticed there is a string cart[50] and int index = 0which you did not use throuoght the whole code except printing it at the end of the code. I am guessing that you want to add the fruit into the cart but it seems like you have not done so.
double price[50];
while (key != -1) {
double current = 0.0;
cout << "Enter fruit code (<-1> to stop): ";
cin >> key;
if (key == -1) break;
cout << getItemName(key) << endl;
cout << "Enter weight <kg> : ";
cin >> weight;
cart[index] = getItemName(key);
price[index] = prices[key] * weight;
total += price[index];
index++;
}
for (int i = 0; i < index; i++) {
cout << cart[i] << " " << price[i] << endl;
}
I have added some code so that cart[index] = getItemName(key). When you print each element of cart, it will now work. Also, current = prices[key] * weight is the correct one, not addition (unless your rules are different).
on a side note are you malaysian
I'm working on a program that I've seen other people do online except I'm trying to use functions to complete it to make it somewhat more challenging for me to help me better understand pointers and vectors. The problem I'm having in xcode is I keep getting this error..
Expected ';' after top level declarator
right here on my code,
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers) //<<< Error
{
cout << fixed << setprecision(2);
...
Where I am trying to use vector numbers in my function. Basically I want the numbers from the function passed back so that I can use them in another function I have not created yet. I've googled this error and it seems like no one can give a straight answer on how to fix this problem. Is anyone familiar with how to correct this? By no means is this code finished I'm just trying to get information regarding vectors as a parameter because from what I'm seeing syntax wise on other sites it looks to be correct. Thanks for your feedback.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
using namespace std;
struct menuItemType{
string menuItem;
double menuPrice;
};
void getData(menuItemType (&mlist)[8]);
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
int main() {
vector<int> temp;
menuItemType menuList[8];
getData(menuList);
showMenu(menuList,temp);
/*
cout << menuList[0].menuItem << " " << menuList[0].menuPrice << endl;
cout << menuList[1].menuItem << " " << menuList[1].menuPrice << endl;
*/
return 0;
}
void getData(menuItemType (&mlist)[8]){
string Str;
ifstream infile;
infile.open("cafe135.txt");
if(infile.is_open())
{
for (int i = 0; i < 8; ++i){
infile >> mlist[i].menuItem >> mlist[i].menuPrice;
}
}
else cout << "Unable to open file";
}
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
{
cout << fixed << setprecision(2);
string choice;
cout << "Would you like to view the menu? [Y] or [N]: ";
cin >> choice;
cout << endl;
int x = 3;
int count = 1;
while (choice != "Y" && choice != "N" && choice != "y" && choice != "n")
{
if (count == 4){
return;
}
cout << "Error! Please try again ["
<< x
<< "] selections remaining: ";
cin >> choice;
cout << endl;
x--;
count++;
}
if (choice == "N" || choice == "n"){
return;
}
else
{
cout << "___________ Breakfast Menu ___________" << endl;
for (int i = 0; i < sizeof(menu_List)/sizeof(menu_List[0]); ++i)
{
cout << "Item "
<< (i+1)
<< ": "
<< menu_List[i].menuItem
<< " "
<< menu_List[i].menuPrice
<< endl;
}
cout << endl;
string itemSelection = " ";
//int str_length = 0;
cout << "Select your item numbers separated"
<< " by spaces (e.g. 1 3 5) Select 0 to cancel order: ";
cin.ignore();
getline(cin, itemSelection);
if (itemSelection == "0")
{
return;
}
vector<int> vectorItemSelection;
stringstream text_stream(itemSelection);
string item;
while (getline(text_stream, item, ' '))
{
vectorItemSelection.push_back(stoi(item));
}
int n = vectorItemSelection.size();
int arr[n];
for (int i = 0; i < n; i++)
{
arr[i] = vectorItemSelection[i];
}
}
}
Compare how menu_List is declared in this line
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
and this line
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
The first one is correct.
But I have to agree with the comments above, you are mixing up a lot of different things here. Just use vectors, 99% of the time it's the right thing to do anyway. and it's easier to learn one thing at a time.
Prefer to write your code like this
void getData(vector<menuItemType>&);
void showMenu(vector<menuItemType>&, vector<int> numbers);
int main() {
vector<int> temp;
vector<menuItemType> menuList(8);
...
See? Just use vectors everywhere.
I must write a program where the user can choose to practice with topic addition or topic multiplication that starts with a self-driven menu.
It must keep track of questions answered right, wrong and the number of questioned asked.
Which my current program is doing within each module(topic). Example Addition keeps track of the questions while the user is practicing Addition only and Multiplication does the same.
However, they are not being feedback to main, so they are not being added or displayed before the user can select another topic to practice or to exit the program.
Currently it is only to keeping track of the question (right /wrong/ total of questions) for each module (topic).
My goal is for the values to be passed to main and display the total number (right /wrong/ total of questions) before the user exits the program, but at the same time I must display the number of question in the Additional Topic and the Multiplication topic and provide a total.
Example Table of Addition, Multiplication and Totals ?
This is the code I have to start with. Can someone help me in how to code to return values of the (right /wrong/ total of questions) of the two topics and accomplish to display something like the table information.
******************************************************************************* /
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <string> // String managment funtions.
#include <iostream> // For input and output
#include <cmath> // For math functions.
#include <math.h>
#include <cstdlib>
using namespace std;
////////////////////////////////////////////////////////////////////////
// Implementing menu driven programs.
// Function Prototypes.
int menu();
void sums();
void products();
int main()
{
srand(time(0));
int option;
do {
option = menu();
switch (option) {
case 1: {
sums();
break;
}
case 2: {
products();
break;
}
default:
cout << "Program exit" << endl;
}
} while (option != 6);
return 0;
}
int menu()
{
cout << "Please select an option" << endl;
cout << "1) Practice with Addition " << endl;
cout << "2) Pratice with Multiplication " << endl;
cout << "3) Exit the program " << endl;
int option;
cin >> option;
return option;
}
void sums()
{
string keepgoing;
unsigned int quantity_total_questions = 0U;
unsigned int quantity_wrong_answers = 0U;
unsigned int quantity_correct_answers = 0U;
do {
const int minValue = 10;
const int maxValue = 99;
int y = (rand() % (maxValue - minValue + 1)) + minValue;
// cout<< " the random number is y "<< y << endl;
int x = (rand() % (maxValue - minValue + 1)) + minValue;
// cout<< " the random number is x "<< x << endl;
cout << "What is " << x << " + " << y << " =" << endl;
int answer;
cin >> answer;
if (answer == (x + y)) {
cout << "Great!! You are really smart!!" << endl;
++quantity_correct_answers;
++quantity_total_questions;
}
else {
cout << "Oh Sorry Try Again." << endl;
++quantity_wrong_answers;
++quantity_total_questions;
}
cout << "Right: " << quantity_correct_answers;
cout << " Wrong: " << quantity_wrong_answers;
cout << " Total Questions: " << quantity_total_questions << endl;
cout << "Do you want to play again? [enter y for yes or n for no]" << endl;
cin >> keepgoing;
} while (keepgoing == "y");
}
void products()
{
{
string keepgoing;
unsigned int quantity_total_questions = 0U;
unsigned int quantity_wrong_answers = 0U;
unsigned int quantity_correct_answers = 0U;
do {
const int minValueOne = 0;
const int maxValueOne = 9;
const int minValueTwo = 10;
const int maxValueTwo = 99;
int y = (rand() % (maxValueOne - minValueOne + 1)) + minValueOne;
// cout<< " the random number is y "<< y << endl;
int x = (rand() % (maxValueTwo - minValueTwo + 1)) + minValueTwo;
// cout<< " the random number is x "<< x << endl;
cout << " What is " << x << " x " << y << " =" << endl;
int answer;
cin >> answer;
if (answer == (x * y)) {
cout << "Great!! You are really smart!!" << endl;
++quantity_correct_answers;
++quantity_total_questions;
}
else {
cout << "Oh Sorry Try Again." << endl;
++quantity_wrong_answers;
++quantity_total_questions;
}
cout << "Right: " << quantity_correct_answers;
cout << " Wrong: " << quantity_wrong_answers;
cout << " Total Questions: " << quantity_total_questions << endl;
cout << "Do you want to play again? [enter y for yes or n for no]" << endl;
cin >> keepgoing;
} while (keepgoing == "y");
}
}
I would create a structure that contains the number of total answers and number of correct answers—the incorrect ones can be inferred—and then pass a reference to an instance of the structure to the respective sums() and products() functions.
Those functions can then populate the structure elements and when they return, your main function can read them out, knowing exactly how many questions were asked, how many were answered, or whatever other information you want to record and retrieve.
I am getting this error every time I try to run my program.
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of
'std::logic_error' what(): basic_string::_M_construct null not valid
#include <iostream>
#include <string>
using namespace std;
struct Bin
{
string desc;
int partsQty;
};
void addParts(Bin bList[], int i);
void removeParts(Bin bList[], int i);
int main() {
char response;
int binNumber;
const int NUM_OF_BINS = 11;
Bin binList[NUM_OF_BINS] = {
{0,0},
{"Valve", 10},
{"Earing",5},
{"Bushing",15},
{"Coupling",21},
{"Flange",7},
{"Gear",5},
{"Gear Housing",5},
{"Vaccum Gripper",25},
{"Cable",18},
{"Rod",12}
};
for(int i=1;i < 11;i++)
{
cout << "Bin #" << i << " Part: " << binList[i].desc << " Quantity " << binList[i].partsQty << endl;
}
cout << "Please select a bin or enter 0 to terminate";
cin >> binNumber;
cout << "Would you like to add or remove parts from a certain bin?(A or R)";
cin >> response;
if(response == 'a')
addParts(binList, binNumber);
else if(response == 'r')
removeParts(binList, binNumber);
return 0;
}
void addParts(Bin bList[], int i)
{
int parts;
int num;
cout << "How many parts would you like to add?";
cin >> num;
parts = bList[i].partsQty + num;
cout << "Bin # " << i << " now contains " << parts << " parts";
}
void removeParts(Bin bList[], int i)
{
int parts;
int number;
cout << "Which bin would you like to remove parts to?";
cin >> i;
cout << "How many parts would you like to remove?" << endl;
cin >> number;
parts = bList[i].partsQty - number;
if(parts < 0)
cout << "Please enter a number that isn't going to make the amount of parts in the bin negative.";
cin >> number;
parts = bList[i].partsQty - number;
cout << "The remaining amount of parts in bin #" << i << " is " << parts;
}
It comes from:
{0,0}
in your list of initializers for binList. 0 is not a correct initializer for std::string. You could perhaps use {"", 0} instead, or even {}.
Another idea might be to revise your program logic so that you do not require a dummy entry at the start of the array.