-2

I'm trying to get user input of names to store in a vector. Every time I run through the for loop, it always takes blank input in the temp string variable the first time through the loop. What I get when I run this program is something like:

,
Dylan, Bob
Brown, Mark
Rogers, Mr

Thanks for any help

Sorry first post =P Heres the code:

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <fstream>
using namespace std;

void getNames(vector<string> &n, int&);
void displayNames(vector<string> &n, int&);
void saveNames(vector<string> &n, int&);
void readNames(vector<string> &n, int&);
void sortNames(vector<string> &n, int&);

int main(){

    vector<string> names;
    int b = 0;
    int choice;

    while(choice != 5){
          cout << "1 - Enter a Character" << endl; 
          cout << "2 - Display List of Characters" << endl;
          cout << "3 - Save List of Characters to File" << endl;
          cout << "4 - Read List of Characters from File" << endl;
          cout << "5 - Exit the program" << endl << endl; 

          cin >> choice;

          switch(choice){
              case 1: getNames(names, b); break;
              case 2: displayNames(names, b); break;  
              case 3: saveNames(names, b); break;  
              case 4: readNames(names, b); break; 
          }
    }
    return 0;

}

void getNames(vector<string> &n, int &b){

    string temp;

    cout << "Enter Names. Press \'quit\' to stop." << endl;

    for(b; temp != "quit"; b++){

        getline(cin, temp);
        if(temp == "quit"){
            break;
        }else{

        int space = temp.find(' ', 0);

        string inPut = temp.substr((space+1), temp.length());
        inPut += ", ";
        inPut += temp.substr(0, space);

        n.push_back(inPut);
        }

    }

}

void displayNames(vector<string> &n, int &b){

    for(int c=0; c < b; c++){
        cout << n[c] << endl;
    }

}

void saveNames(vector<string> &n, int &b){
    ofstream outFile;
    outFile.open("names.txt", ios::app);

    if(!outFile.fail()){

        for(int i=0; i < b; i++){

            outFile << n[i] << endl;
        }
        cout << "Names written to File" << endl;

    }else{

        cout << "ERROR: File could not be opened" << endl;
    }
    outFile.close();
}

void readNames(vector<string> &n, int&){
    string line;
    ifstream inFile("names.txt");

    if(inFile.is_open()){
        while(getline(inFile, line)){
            cout << line << endl;
        }
        inFile.close();
    }else{
        cout << "Cannot open File" << endl;
    }

}

void sortNames(vector<string> &n, int&){

    //for(int i=0; i < b; i++){}

}
  • 2
    You have an error in your code. – Pete Becker Mar 29 '16 at 20:10
  • Please provide a [minimal complete verifiable example](http://stackoverflow.com/help/mcve). Post your code. – Ivan Gritsenko Mar 29 '16 at 20:11
  • I ran your code through my debugger and the problem is the statement on line 115. Please run your debugger and confirm this is correct. – Thomas Matthews Mar 29 '16 at 20:13
  • void saveNames(vector &n, int &b){ ofstream outFile; outFile.open("names.txt", ios::app); if(!outFile.fail()){ for(int i=0; i < b; i++){ outFile << n[i] << endl; } cout << "Names written to File" << endl; }else{ cout << "ERROR: File could not be opened" << endl; } outFile.close(); } – Daniel Evans Mar 29 '16 at 20:16
  • @DanielEvans, you should put your saveNames function into your question instead of a comment so it would be easier for us to see. – John Odom Mar 29 '16 at 20:24
  • 1
    Do you use `cin >> variable` anywhere in the program before you call `getNames`? – Barmar Mar 29 '16 at 20:26
  • sorry, yeah the one i put in the comment is the wrong function, I just put the right one in the question – Daniel Evans Mar 29 '16 at 20:27

2 Answers2

0

Why are you using a for loop? is better to use a while loop like so:

void getNames(vector<string> &n, int &b)
{
 string temp;
 cout << "Enter Names. Press \'quit\' to stop." << endl;
 getline(cin, temp);
 while(temp != "quit")
 {
  int space = temp.find(' ', 0);
  string inPut = temp.substr((space+1), temp.length());
  inPut += ", ";
  inPut += temp.substr(0, space);
  n.push_back(inPut);
  getline(cin, temp);
 }
 ...//the rest of your code...
}

I didn't answer the question, sorry... the first input is the termination character of your last cin... std::getline (string)

DIEGO CARRASCAL
  • 1,918
  • 12
  • 16
  • Thanks, what do you mean by "the first input is the termination character..."? – Daniel Evans Mar 29 '16 at 21:06
  • @ Daniel Evans if you don't specify a delimitation character for the end of line then the "enter" (new line) is assumed to be, so it's possible that the last time you press enter on a cin is that first input. – DIEGO CARRASCAL Mar 29 '16 at 21:13
0

By fixing your curly braces your getNames() function works for me as expected. Maybe this is an oversight from posting your code, but you are missing a curly brace to end your for loop and function call for GetNames(). Compiling and using this code produces the expected output:

void getNames(vector<string> &n, int &b){

    string temp;

    cout << "Enter Names. Press \'quit\' to stop." << endl;

    for(b; temp != "quit"; b++){

        getline(cin, temp);
        if(temp == "quit"){
            break;
        }else{

            int space = temp.find(' ', 0);

            string inPut = temp.substr((space+1), temp.length());
            inPut += ", ";
            inPut += temp.substr(0, space);

            cout << inPut << endl; //Testing string transformation before insertion.

            n.push_back(inPut);
        }
    }
}

Passing the names: "Bob Dylan", "Jerry McQuire", and "Some Guy" resulted in the output

Dylan, Bob
McQuire, Jerry
Guy, Some

It is possible that there is an error somewhere else in the code if your first element in the Vector is always blank. The error is possibly in the saveNames() or readNames() functions. But the strings are input and transformed correctly here. It's beneficial to post all the code relevant to your question ahead of time.

Please include this at the top of getNames():

cin.clear();
cin.ignore(10000, '\n');

This will clear the cin buffer to a new line so the initial choice from main() doesn't get put in to the vector unexpectedly.

Winter
  • 122
  • 7
  • Thanks, yeah I have the curly braces right I just didn't copy it here correctly. Okay I'll edit my post with the full code – Daniel Evans Mar 29 '16 at 21:09
  • When you print out the vector, don't print the 0 element. The empty value is coming from the cin statement in main() when the user picks between option 1-5. – Winter Mar 29 '16 at 21:14
  • Thanks it worked! Why does the value from cin get stored in the vector though? – Daniel Evans Mar 29 '16 at 21:25
  • It's because of the way that the getNames() function is implemented. Since the for loop is only conditioned on whether temp != quit, the for loop runs immediately upon entering the function. The cin buffer still contains "1". This gets transformed to ", " and then input in to the vector. On the NEXT iteration the user gets to use their input. I'll add to my answer to give you a proper fix for it. – Winter Mar 29 '16 at 21:37