Solve C++ Vector Question: #include, for Loop, getline(), vector.pop_back()

  • C/C++
  • Thread starter FallArk
  • Start date
  • Tags
    C++ Vector
In summary, the conversation discusses the trouble with a C++ question regarding a program that asks for user inputs, stores them in a vector, and eliminates a specific value. The code provided has some issues with properly using the getline function and declaring the vector size. The code also lacks robustness and may lead to unexpected results. Suggestions are given for improvements, such as using string methods and considering potential user errors.
  • #1
FallArk
127
0
I ran into some trouble with a C++ question. I need to make a program that will run like this:
Example run 1:
How many names do you want (max 99)? 5
Enter name #1: Adam Apple
Enter name #2: Betty Boop
Enter name #3: Charles Chaplin
Enter name #4: Debbie Dali
Enter name #5: Elaine Eggbert
What name do you want to eliminate? Adam Apple
Here is the list in reverse order, skipping Adam Apple...
Elaine Eggbert
Debbie Dali
Charles Chaplin
Betty Boop
ER]​

This is what I came up with :
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
    int x = 0;
    int i = 0;
    vector<string> userName(x);
  cout << "How many names do you want (max 99) ? ";
  cin >> x;
  if (x > 99) {
      cout << "Out of memory!";
      return 0;
  }
  for (i = 0; i < x; ++i) {
      cout << "Enter name #" << i + 1 << ": ";
      cin.ignore();
      getline(cin,userName.at(i));
  }
}
I was trying to use a for loop to ask for inputs and then assign them to the vector. Then i can use the vectr.pop_back() command to eliminate values. But the program just end itself after displaying Enter name #1:. I'm not sure whether the getline is not used correctly or i messed up setting the vectors.
Thanks for the great help so far!
 
Technology news on Phys.org
  • #2
The main problem with your code is that the vector userName is declared to have 0 components, basically then a useless vector. Even though the vector class is "dynamic", it is up to the programmer to make sure that a vector has enough components for its intended use. So replace the declaration with:
vector userName(99);

Next, I/O in C++ (as in other languages) can be tricky. Class cin's method getline reads all the characters on a line of input, including the terminating return character. However, this return character is not put into the target string. So when you put ignore into your loop, it will ignore the first character of the name typed by the user. However, when cin inputs the integer x, the terminating return character is not read. So before starting your loop to read the names, you want to get rid of this return char. Do this with an ignore(). If you don't do this, the first name you read will be just the return character, resulting in an empty string!

Here's what you wrote, but I tweaked it just a bit:

Code:
   int x, i;
   vector<string> userName(99);
   cout << "How many names do you want (max 99) ? ";
   cin >> x;
   if (x > 99) {
      cout << "Out of memory!";
      return 0;
   }
   cin.ignore();
   for (i = 0; i < x; ++i) {
      cout << "Enter name #" << i + 1 << ":";
      //      cin.ignore(); this would strip off the 1st char of name
      getline(cin, userName.at(i));
   }
   cout << "What name to ignore?";
   string skip;
   getline(cin, skip);
   /* Now use a for loop starting at x-1 that decrements to 0.
       Output the component only if it is != skip
   */

Finally, the above is not very "robust". The user can get unexpected results. For example, if she types the name Ali, but then types the name to be skipped as ali, Ali does not get skipped in the output. You can try and make the program better by using string methods and trying to think of all (stupid) things a user can do.
 
Last edited:
  • #3
johng said:
The main problem with your code is that the vector userName is declared to have 0 components, basically then a useless vector. Even though the vector class is "dynamic", it is up to the programmer to make sure that a vector has enough components for its intended use. So replace the declaration with:
vector userName(99);

Next, I/O in C++ (as in other languages) can be tricky. Class cin's method getline reads all the characters on a line of input, including the terminating return character. However, this return character is not put into the target string. So when you put ignore into your loop, it will ignore the first character of the name typed by the user. However, when cin inputs the integer x, the terminating return character is not read. So before starting your loop to read the names, you want to get rid of this return char. Do this with an ignore(). If you don't do this, the first name you read will be just the return character, resulting in an empty string!

Here's what you wrote, but I tweaked it just a bit:

Code:
   int x, i;
   vector<string> userName(99);
   cout << "How many names do you want (max 99) ? ";
   cin >> x;
   if (x > 99) {
      cout << "Out of memory!";
      return 0;
   }
   cin.ignore();
   for (i = 0; i < x; ++i) {
      cout << "Enter name #" << i + 1 << ":";
      //      cin.ignore(); this would strip off the 1st char of name
      getline(cin, userName.at(i));
   }
   cout << "What name to ignore?";
   string skip;
   getline(cin, skip);
   /* Now use a for loop starting at x-1 that decrements to 0.
       Output the component only if it is != skip
   */

Finally, the above is not very "robust". The user can get unexpected results. For example, if she types the name Ali, but then types the name to be skipped as ali, Ali does not get skipped in the output. You can try and make the program better by using string methods and trying to think of all (stupid) things a user can do.

This is what I did:
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
int x = 0;
int i = 0;
vector<string> userName(99);
string userSkip;
cout << "How many names do you want (max 99) ? ";
cin >> x;
if (x > 99) {
    cout << "Out of memory!";
    return 0;
}
for (i = 0; i < x; ++i) {
    cout << "Enter name #" << i + 1 << ": ";
    cin.ignore();
    getline(cin,userName.at(i));
}
cout << "What name do you want to eliminate? ";
getline(cin,userSkip);
cout << "Here is the list in reverse order, skipping " << userSkip << "...";
for (i = x - 1; i > 0; --i){
        /* for some reason, the userName.at(i) will not run, did i do something wrong? this for loop is confusing. */
    cout << userName.at(i) << endl;
    if (userSkip == userName.at(i)) {
        userName.at(i) = ""; // I don't know how to get rid of a value
    }
    else {
        cout << "The name [" << userSkip << "] was not encountered.";
    }
}
}

I need to get rid of values "userSkip" but i don't really know how, and the for loop is not executing properly.
Thanks for the help!
 
  • #4
First, you ignored (not on purpose, I hope) my previous correction to your code that inputs the list of names. Again, as you wrote the input loop, every name after the first has its first letter removed!

Next, the original specification said nothing about deleting name userSkip from vector userName. However, if you want to do so, the following program does this. I recommend that you study this complete correct program. If you have questions about it, post again.

Code:
#include <iostream>
#include <vector>
#include <cctype>
#include <string>
using namespace std;

int main() {
   int x = 0;
   int i = 0;
   vector<string> userName(99);
   string userSkip;
   cout << "How many names do you want (max 99) ? ";
   cin >> x;
   if (x > 99) {
      cout << "Out of memory!";
      return 0;
   }
   cin.ignore();
   for (i = 0; i < x; ++i) {
      cout << "Enter name #" << i + 1 << ": ";
      getline(cin, userName.at(i));
   }
   cout << "What name do you want to eliminate? ";
   getline(cin, userSkip);
   cout << "Here is the list in reverse order, skipping " << userSkip << "...\n";
   int skipIndex = -1;
   for (i = x - 1; i >= 0; --i) {
      if (userSkip != userName.at(i)) {
         cout << userName.at(i) << endl;
      } else {
         skipIndex = i;
      }
   }
   if (skipIndex == -1) {
      cout << userSkip << " not in the list\n";
   } else { // physically remove name userSkip from the vector
      for (i = skipIndex; i < x - 1; i++) {
         userName.at(i) = userName.at(i + 1);
      }
      userName.resize(x - 1);
      // now verify userSkip was deleted from vector userName:
      cout << "List with " << userSkip << " deleted:\n";
      for (i = 0; i < userName.size(); i++) {
         cout << userName.at(i) << endl;
      }
   }
   return(0);
}
 
  • #5
Whoops! Didn't see the comment on that loop.
One more question: Is there a way to output the list in reverse (I know how to do this) and if the user entered something that is not inside the vector, the program will output "This **** is not encountered" ?
update: I changed vector to array, I think that's what my instructor wants us to do.
This is what I have so far:
Code:
#include <iostream>
#include <string>
using namespace std;
int main() {
int x = 0;
int i = 0;
string userName[99];
string userSkip;
cout << "How many names do you want (max 99) ? ";
cin >> x;
if (x > 99) {
    cout << "Out of memory!";
    return 0;
}
cin.ignore();
for (i = 0; i < x; ++i) {
    cout << "Enter name #" << i + 1 << ": ";
    getline(cin,userName[i]);
}
cout << "What name do you want to eliminate? ";
getline(cin,userSkip);
cout << "Here is the list in reverse order, skipping " << userSkip << "..." << endl;

for (i = x - 1; i >= 0; --i) {
     if (userSkip != userName[i]) {
         cout << userName[i] << endl; // this is where I am confused.
      }
cout << "The name [" << userSkip << "] was not encountered.";
}

}
 
Last edited:

FAQ: Solve C++ Vector Question: #include, for Loop, getline(), vector.pop_back()

What is the purpose of the #include statement in C++?

The #include statement is used to include external libraries or header files into your C++ program. This allows you to access pre-defined functions and data types that are not included in the standard C++ library.

How does the for loop work in C++?

The for loop is a control flow statement that allows you to execute a block of code repeatedly, based on a specified condition. It consists of three parts: an initialization expression, a condition, and an increment/decrement expression. The loop will continue to execute until the condition becomes false.

What is the purpose of the getline() function in C++?

The getline() function is used to read a line of text from an input stream, such as the console or a file. It takes in two parameters: the input stream and a string variable to store the input. This function is commonly used to read user input in C++ programs.

What does the vector.pop_back() function do in C++?

The vector.pop_back() function removes the last element from a vector and reduces its size by one. This is commonly used when you want to remove elements from the end of a vector, as opposed to the beginning or middle.

How do you access elements in a vector in C++?

To access elements in a vector, you can use the square bracket notation, with the index of the element you want to access inside the brackets. For example, if you have a vector called myVector and you want to access the third element, you would use myVector[2]. Remember that vector indices start at 0, so the third element has an index of 2.

Similar threads

Replies
8
Views
2K
Replies
118
Views
8K
Replies
5
Views
2K
Replies
4
Views
5K
Replies
39
Views
4K
Replies
22
Views
3K
Replies
65
Views
5K
Back
Top