Home > database >  Creating loops and using pushback code help c
Creating loops and using pushback code help c

Time:05-23

I am trying to have the user choose how many names they would like to add, once they do to use push.back to add on the list. I am new to programming and very confused. Here is the code:


int main()
{
    int numNames;
    std::cin >> numNames;
    vector<string> names;
    numNames = read_integer("How many names would you like to add?");

    for (int i = 0; i < numNames; i  )
    {
        names[i] = read_string("Enter name:");
        i  ;

        while (cin >> numNames)
        {
            names.push_back(read_string("First value:"));
        }
    }

CodePudding user response:

When using the std::vector there is no need to have the user enter the number of names beforehand. That is the benefit of having std::vector handle the memory management for you. You simply read and validate the input and .push_back() to the vector until the user is done. Using getline() for input allows you to read names with whitespace (e.g. "first last") while using std::cin would stop reading at the first whitespace encountered.

Using getline() also provides a simple way for the user to indicate they are done entering names. Having the user press Enter alone on a new line instead of a name will result in the string filled by getline() having .size() == 0. You simply break your read-loop at that point.

A short example of reading names and adding to std::vector<std::string> can be done similar to:

#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> names {};    /* vector of strings */
    std::string tmp {};                   /* temp string */
    
    std::cout << "Enter names below, [Enter] alone when done\n\n  name: ";
    
    /* read line while input size isn't 0 */
    while (getline (std::cin, tmp) && tmp.size() != 0) {
        names.push_back (tmp);            /* add input to vector */
        std::cout << "  name: ";          /* next prompt */
    }
    
    std::cout << "\nnames collected:\n\n";
    for (const auto& name : names) {      /* loop over each name and output */
        std::cout << name << '\n';
    }
}

Example Use/Output

$ ./bin/vector-string-names
Enter names below, [Enter] alone when done

  name: Mickey Mouse
  name: Minnie Mouse
  name: Pluto (the dog)
  name: Donald Duck
  name: Daffy Duck
  name: Daisy Duck
  name: Hughie Duck
  name: Louie Duck
  name: Dewy Duck
  name:

names collected:

Mickey Mouse
Minnie Mouse
Pluto (the dog)
Donald Duck
Daffy Duck
Daisy Duck
Hughie Duck
Louie Duck
Dewy Duck

Additional Notes

While using namespace std; is a convenience for short example programs, see Why is “using namespace std;” considered bad practice?.

Never std::cin >> numNames; without checking the stream-state after the input. (especially when a numeric conversion is involved). A simple:

  if (!(std::cin >> numNames)) {
    std::cerr << "error: invalid integer input.\n";
    return 1;
  }

To ensure the user provides valid integer input, you can loop continually until a valid int is entered and then break the read loop after you have a valid integer. You can use .clear() and use .ignore() to remove any invalid characters from stdin after a failed input and before your next input.

CodePudding user response:

I noticed when you do your loop, there is a simpler way to do so that will prevent some additional and unwanted bugs:

    for (int i = 0; i < numNames;   i)
    {
        names[i] = read_string("Enter name:");

        while (cin >> numNames)
        {
            names.push_back(read_string("First value:"));
        }
    }

this way, you are not doubling the value of i. When starting a for-loop, using i will add 1 to i, but will not update i and only returns i with 1 added to it. Using i updates and returns i plus 1, and you nolonger need to have the extra line of i , and this will prevent doubling i.

  •  Tags:  
  • c
  • Related