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.