C++ vector push_back function - c++

So I am pretty new to coding and am having some issues with storing user input into a vector using the push_back function. can some one tell me what I am doing wrong?
vector<int> user_nums;
switch(selection){
case 'P':
case 'p':
if(user_nums.empty()){
cout << "[]- list is empty" << endl;
}else{
for(auto nums: user_nums)
cout <<"[ " << nums << " ]" << endl;
}
break;
case 'A':
case 'a':
int new_num;
cout << "\nEnter a number you would like to add: ";
cin >> new_num;
user_nums.push_back(new_num);
cout << new_num << " was added" << endl;
break;
This is in a do while loop. The code executes just fine, the problem is when I prompt the user to add a new number the value does not store in the vector. So when the user makes the selection to print the numbers, the list still shows empty.

So, you're missing the most relevant sections of your code here. You should really be posting a minimal, reproducible example. Often the process of creating one will cause you to find your problem.
In this case though, it's obvious enough. There's a loop wrapping all this code. The vector is declared inside the loop. That means, at the bottom of the loop the vector will be destroyed, and then as the loop is executed again, a new empty vector will be created.
The solution is to move the declaration of the vector outside the loop.
If I've guessed wrong about the structure of the code you haven't shown us, then please follow the guideline I linked to above.

Related

Beginner C++ Voting Program using const literal

This program I came across on another forum is a voting program, someone was having issues with compiling. Any answer that was given didn't really match up with what the programmer wanted. So I am here to get some effective answers after attempting to edit the code myself.
The current issue I am having is when I input the variable, it still runs an infinite loop. What am I not doing properly for the design to perform, until I input 5 votes?
#include <iostream>
using namespace std;
const int ev = 5; //max. # of votes
int votesA = 0, votesB = 0, votesC = 0, spoiltvotes = 0; //total votes already initialized globally
int vote; //input variable
int main()
{
//loop over the voting stations
int i;
for(i = 0; i <= ev; i++)
{
//loop over the votes
cout << "Enter your vote: \t";
cin >> vote;
while(vote <= 5)
{
switch(vote)
{
case 1: votesA++;
break;
case 2: votesB++;
break;
case 3: votesC++;
break;
default: spoiltvotes++;
}
}
}
//display results neatly
cout << "# of votes for candidate A: \t" << votesA;
cout << "\n # of votes for candidate B: \t" << votesB;
cout << "\n # of votes for candidate C: \t" << votesC;
cout << "\n # of spoilt votes: \t" << spoiltvotes;
return 0;
}
Updated Result: I have fixed the infinite loop but for some reason the loop is still iterating 6 times instead of 5, giving me large tallies of numbers instead of single-digits.
#include <iostream>
using namespace std;
int main()
{
const int ENDvote = 5; //max. # of votes
//loop over the voting stations
int vote;
int spoiltvotes;
for(vote = 0; vote >= ENDvote; vote++)
cout << "1. Candidate A\t 2. Candidate B\t 3. Candidate C" << endl;
{
//loop over the votes
cout << "Enter your vote: \t";
cin >> vote;
switch(vote)
{
case 1:
cout << "# of votes for candidate A:\t" << vote;
break;
case 2:
cout << "# of votes for candidate B:\t" << vote;
break;
case 3:
cout << "# of votes for candidate C:\t" << vote;
break;
default:
cout << "# of spoilt votes:\t" << spoiltvotes;
break;
}
}
return 0;
}
There is an obvious issue to your code.
When you enter your for loop : ‘for(i = 0; i <= ev; i++)’ you get to the ‘cin>>vote;’ When you get the vote if ‘vote<=5’ the loop with go on forever due to the while loop. Once you enter the while loop VOTE NEVER CHANGES. So, if the while loop condition is fulfilled, it will always be true since(again) vote doesn’t change.
Fred Larson said what I am saying essentially.
I am new to stack overflow so anything you think I should be doing, please tell me.
Others have already commented on what's the problem with your program, the while loop would never break since vote is never getting updated and if the input value in vote is <=5, it shall remain to be so and end up being an infinite while loop.
A while loop within a for loop is usually not something you'd want and should look hard at the code and see if that's what you really want. If not, refactor it out to stick with either one of them, not both.
Your problem appears to be in a similar vein. From your program, it seems that you want to read in the votes polled at the 5 voting stations and then count the number of votes that each candidate received (or went waste).
If you go the for loop route, you just need to iterate over the loop, read in the number of votes (alongwith input validations), do the switch case and then move on to the next iteration of the for loop.
If you go the while loop route, then just have a while loop to read in five votes, something like
while(std::cin>>vote) {
switch(...
and do pretty much the same stuff.
Also, global variables are (again) usually a bad idea, especially if they are non-const. Move them into your main().
Also, do take care that a break statement only breaks the inner-most loop. So, doing something like
while(true) {
int x = 1;
switch(x) {
case 1:
break;
}
}
will not break the while loop,.

Using object when out of scope?

I'm working on a school assignment require to create a char LinkedList from user string input based on a menu of options:
Enter new string and store as linked list character of in an LinkedList class.
Get current length from the LinkedList.
Find index of character in this linked list.
Append another LinkedList to this LinkedList.
I have everything working fine, but now I'm stuck at the menu option part.
So let's say I choose option 1 to enter a string, and then I decide to use that object for case 2 and 3 to get the size and find index. That would not work because the object will be destroyed when out of scope. Is there any proper way that I can use to implement this ?
Simple Code Below
switch(option){
case 1:
LinkedList ls1(getInput());
ls1.printList();
break;
}
case 2:
cout << "Size of LinkedList: " <<ls1.getSize() << endl; //wouldn't work because ls1 got destroyed when out of scope.
}
If you want to expand the scope of an object, you declare it at a higher scope. You probably have a while loop asking for input, and then switching on that input? If you want your LinkedList to survive successive iterations of the loop, you'll need to declare it before the loop starts.
LinkedList ls1; // required default constructor
int option = 3;
do
{
std::cout << "Enter 1 to create new list. 2 to print current list. 3 to quit: ";
std::cin >> option;
switch(option)
{
case 1:
ls1 = getInput(); // requires conversion from getInput()'s return type and copy (or preferably move) assignment operators
ls1.printList();
break;
case 2:
std::cout << "Size of LinkedList: " <<ls1.getSize() << std::endl;
break;
}
} while(option != 3);
Try to initiate the object outside the switch statement and after that you could use that object within any switch case.
Example:
ClassName ObjectName(getInput());
switch(option){
case 1: ObjectName.printList();
break;
case 2: cout << "Size of LinkedList: " <<ObjectName.getSize() << endl;
break;
default: break;
}
Declare the object outside the switch statement.
LinkedList ls1(getInput());
switch(option){
case 1:
ls1.printList();
break;
case 2:
cout << "Size of LinkedList: " <<ls1.getSize() << endl;
break;
default:
break;
}

Using switch statements to access functions OOP C++

I've been trying to use switch statements to access different functions in my program and when I compile the code it keeps showing up the default option, regardless of what I input. Am I missing something really obvious here?
All the functions (all voids) are declared in the class. Is this maybe because I am implementing the other 'menu' functions underneath this one?
void bookshop::menu_searchtype() {
std::cout << "Welcome to Hal's Book Emporium!\n\n";
std::cout << "You can search for a book by its:\n";
std::cout << "1. Identification number\n";
std::cout << "2. Title\n";
std::cout << "3. Author\n\n";
std::cout << "Which would you like to use?\n\n";
std::cin >> choice_menu;
int menu_searchtype_no;
switch (menu_searchtype_no) {
case '1':
menu_id();
break;
case '2':
menu_title();
break;
case '3':
menu_author();
break;
default:
std::cout << "We seemed to have run into a problem. Please try again\n\n";
break;
}
}
You are reading values into choice_menu and not menu_searchtype_no which you didnt even initialized.
Your case statement looks like you are comparing for characters. Remove quotes (if you are reading integers and choice_menu is of integer type) and that should let you move further.
You never set menu_searchtype_no, so it has an unspecified value. On very rare occasions this may "equal" '1', '2' or '3' (which is 49, 50 or 51 respectively, if you're using ASCII), but far more likely it'll be some random-looking higher value which will trigger the default case.
I guess you meant to write:
switch (choice_menu) {
and
case 1:
etc.

C++ switch statement. Default not working

I've been searching and trying different things for an hour and can't figure this out. Why doesn't my default work? If I enter 1-4, the output is as expected. However, if I enter any other number or letter, nothing is displayed. I would like the default to display if I enter any other number or letter.
RESOLVED: It was my compiler. Going to use Visual Studio only from now on. (VS didn't show my default at first because I was using it incorrectly.) Thanks to everyone for your responses.
My code:
int main()
{
int num;
cout << "Please enter the code stamped on the storage drive (1-4): ";
cin >> num;
switch (num)
{
case 1:
cout << "The code you entered was 1; therefore, the storage capacity is 2GB." << endl;
break;
case 2:
cout << "The code you entered was 2; therefore, the storage capacity is 4GB." << endl;
break;
case 3:
cout << "The code you entered was 3; therefore, the storage capacity is 16GB." << endl;
break;
case 4:
cout << "The code you entered was 4; therefore, the storage capacity is 32GB." << endl;
break;
default:
cout << "Invalid selection - Please input 1 to 4 only.";
break;
} //end of switch
return 0;
}
The default is working (I've tested it), subject to the following caveats.
First of all, the way your code is structured, you have to enter something. If you just press Enter, nothing will happens because cin >> num will continue waiting for a number.
Secondly, when you enter anything that's not a number, cin >> num fails and leaves num uninitialized. This leads to undefined behaviour in the switch.
You should initialize num (say to 0 or another invalid value) and/or check whether cin >> num has succeeded:
if (cin >> num) {
// the read has succeeded
} else {
// the read has failed
}
Try adding either a '\n' to the end of your default message or a << endl.
Looks like the text from the default is waiting to be flushed.
You could also add a cout.flush(); before the end of your program.
I know this is pointless saying anything as this was a while ago, but for those who have a similar problem look at your code.... case 1: it should instead case '1': the same applies for every other case, then your switch statement will work

Need help fixing strange cin behavior

I'm building a product checkout piece of software and I keep hitting a strange bug. I have a central menu that gets user input. After a function is finished with its task, it sends the user back to the menu. For certain functions, however, the cin.get() I have after the menu prompt bugs out and won't accept the first command given. Here are the relevant code fragments:
The main menu loop:
bool foreverLoopFlag = true;
while (foreverLoopFlag) {
cout << "\nC[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? ";
cin.get(actionChoice);
std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
cout << endl;
actionChoice = toupper(actionChoice);
switch (actionChoice) {
case 'C':
checkoutSoftware(studentMap, productList);
break;
case 'R':
returnSoftware(studentMap, productList);
break;
case 'S':
studentDisplay(studentMap, productList);
break;
case 'P':
productDisplay(studentMap, productList);
break;
case 'Q':
foreverLoopFlag = false;
break;
default:
cout << "Invalid command.\n";
break;
}
}
A problem-child function, studentDisplay:
void studentDisplay(map<string, Student> & studentMap, list<Product> & productList) {
string inputCLID;
cout << "Please enter student CLID: ";
cin >> inputCLID;
if (studentMap.find(inputCLID) != studentMap.end()) {
cout << "\nStudent: " << studentMap[inputCLID].name << " (" << inputCLID << ")\n";
cout << "\tBorrowed items: " << endl;
for (list<Student::LentProduct>::iterator it = studentMap[inputCLID].checkedOut.begin();
it != studentMap[inputCLID].checkedOut.end(); it++) {
cout << "\t\tProduct: " << (*it).name;
cout << "\tDue Date: " << (*it).dateDue << endl;
}
} else {
cout << "\nError: CLID not in database.\n";
}
}
Some of the indention was mangled moving over to SE, I apologize. Here an example of the issue I'm having:
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? s
Please enter student CLID: mrx8394
Student: Mark Xeno (mrx8394)
Borrowed items:
Product: Bluebeard Due Date: 12/14/2013
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? c
Invalid command.
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? q
I tried putting a std::cin.flush() at the beginning of the menu-loop, but that didn't work. I tried doing std::cin.ignore(std::INT_MAX) at the beginning of the menu-loop, but that makes it to where the menu never even shows up. I also tried a std::cin.sync(), but that just makes an infinite cycle of this:
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice?
Please enter a product to checkout:
Error: No such product.
I have no idea where to go from here. I know it is probably just some quirk of the iostream that I'm not picking up on. Any assistant would be appreciated.
EDIT: I do not have enough reputation to upvote or comment on specific answers (all of my rep is on Math.SE!!!), so I'll comment here. #Igor-tandetnik 's solution worked perfectly. I had moved everything else over to a getline, but I suppose that guy just got left in the shuffle. My thanks come in droves.
#qwrrty While it may be folly, I had a specification to meet (don't you just love low level University courses). I don't typically ask for help debugging assignments, but this was the last bug and my knowledge of iostream isn't that deep, but I knew someone on here would know what was bugging out my stream state.
Thanks again guys, cheers!
cin >> inputCLID reads characters up to, but not including, the first whitespace character (in your example, a line feed). That character is left in the stream. It is that character that cin.get(actionChoice) later retrieves.
I tend to think that for interactive input, trying to use stdin and/or cin for reading anything other than a full line of input is folly. There are just too many ways for your program to get confused about what's still on the input stream, and end up in an unrecoverable state.
At the very least I'd modify the program to say what command it thinks is invalid, or product that doesn't exist:
default:
cout << "Invalid command '" << actionChoice << "'\n";
and
cout << "Error: No such product '" << productChoice << "'\n";
That way at least you can get an idea of what input the program is actually using for these variables.