0

Here is a small snippet of my code:

int read_prompt() {
string prompt,fname,lname,input;
int id;
cout << "customers> ";

cin >> prompt;

if (prompt.compare("add") == 0) {
    cin >> id;
    cin >> fname;
    cin >> lname;
    NewCustomer(id,fname,lname);
} else if (prompt.compare("print")==0) {
    print_array();
} else if (prompt.compare("remove")==0) {
    cin >> id;
    RemoveCustomer(id);
} else if (prompt.compare("quit")==0) {
    return 0;
} else {
    cout << "Error!" << endl;
}
read_prompt();
return 0;

}

This works just fine as long as the user doesn't input anything unexpected. One of the test cases this program is supposed to pass inputs "add 125mph Daffy Duck," which id ends up being 125, fname equals mph, and lname equals Daffy. After this function receives all three variables it calls itself again and reprompts the user, which Duck then gets entered which "Error!" gets output obviously.

How would I catch this error as the user enters it? Is cin the best function to use in this regard? I did look up getline(), but I'm a little unsure how to implement it.

dmarzio
  • 345
  • 1
  • 3
  • 9
  • Why not create a menu driven program that allows the user to select the desired function by entering a single number then use a `switch`. You'll avoid many errors and validation code. – ChiefTwoPencils Feb 15 '13 at 20:06
  • 1
    `cin` is not a function; it's an object. As such, it has member functions and there are free functions that can use it. Many of those are extractors, that is, overloads of `operator>>`. – Pete Becker Feb 15 '13 at 20:10

1 Answers1

1

If it were me,

  • I would read the entire line in at once and break it up into white-space-separated tokens using std::istringstream.
  • I would avoid the recusion at all costs.
  • I might add more stringent error checking.

Like this:

#include <vector>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <sstream>
#include <stdexcept>

typedef std::vector<std::string> Args;

std::istream& operator>>(std::istream& is, Args& args) {
    std::string s;
    if(std::getline(is, s)) {
        std::istringstream iss(s);
        args.clear();
        while( iss >> s )
            args.push_back(s);
    }
    return is;
}

void NewCustomer(int, std::string, std::string) {
    std::cout << __func__ << "\n";
}
void RemoveCustomer(int) {
    std::cout << __func__ << "\n";
}
void print_array() {
    std::cout << __func__ << "\n";
}
int read_prompt() {
    Args args;
    while(std::cout << "customers> " && std::cin >> args) {
        try {
            if(args.at(0) == "add") {
                NewCustomer(
                    boost::lexical_cast<int>(args.at(1)),
                    args.at(2),
                    args.at(3));
            } else if (args.at(0) == "print") {
                print_array();
            } else if (args.at(0) == "remove") {
                RemoveCustomer(boost::lexical_cast<int>(args.at(1)));
            } else if (args.at(0) == "quit") {
                return 0;
            } else {
                throw 1;
            }
        } catch(boost::bad_lexical_cast&) {
            std::cout << "Error!\n";
        } catch(std::out_of_range&) {
            std::cout << "Error!\n";
        } catch(int) {
            std::cout << "Error!\n";
        }
    }
}

int main () {
    read_prompt();
}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308