adf
adf

Reputation: 11

How do I disallow cin from forwarding to the next input if I enter more than one word per cin?

On each input of this program, I want the user to be able to type in however many "words" (meaning text separated by spaces/tabs) they desire...but to disallow the user from being able to input words beyond the current cin. For example: if I type John Smith Doe, I want John to be put into 'name', and Smith and Doe to be discarded. Then I want to enter the 'age' and 'weight' without having Smith going to age and Doe going to weight. Currently, if I input John Doe for the name, then age becomes Doe. If I enter John Smith Doe for the name, then age becomes Smith and weight becomes Doe. Can anyone help with this?

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    string name;
    string age;
    string weight;

    //user can enter more than one name (title, first, middle, last, etc.)
    cout << "Enter your name: " << endl;
    cin >> name;

    //if user entered two or more names above,
    //disallow cin from putting name two into 'age'
    cout << "Enter your age: " << endl;
    cin >> age;

    //same thing for weight
    cout << "Enter your weight: " << endl;
    cin >> weight;

    cout << "You typed: " << endl;
    cout << "Name: " << name << endl;
    cout << "Age: " << age << endl;
    cout << "Weight: " << weight << "." << endl;

    return 0;
}

Upvotes: 1

Views: 77

Answers (3)

adf
adf

Reputation: 11

This is the solution I developed. Thank you for your help!

string name;
string age;
string weight;

cout << "Enter your name: " << endl;
//this line allows me to take in a full line (up
//to the newline character) at once
getline(cin, name);
//then i search for the first occurence of a 
//spacebar, or output the whole line if none
//is found
int i = 0;
int len = name.length();
for(; i < len; i++)
{
    if(name[i] == ' ')
    {
        break;
    }
}
//chop off end of variable 'name'
//after first spacebar or leave 
//it whole if no spacebar was
//found
name = name.substr(0, i);

//same thing as above for here
cout << "Enter your age: " << endl;
getline(cin, age);
i = 0;
len = age.length();
for(; i < len; i++)
{
    if(age[i] == ' ')
    {
        break;
    }
}
age = age.substr(0, i);

//ditto for here
cout << "Enter your weight: " << endl;
getline(cin, weight);
i = 0;
len = weight.length();
for(; i < len; i++)
{
    if(weight[i] == ' ')
    {
        break;
    }
}
weight = weight.substr(0, i);

cout << "You typed: " << endl;
cout << "Name: " << name << endl;
cout << "Age: " << age << endl;
cout << "Weight: " << weight << endl;

Upvotes: 0

user2249683
user2249683

Reputation:

Read the stream line by line, pass each line to a istingstream and read the fields of interest:

// Read Fields [Teminating State]
inline std::istream& read_fields(std::istringstream& line_stream)
{
    return line_stream;
}

// Read Fields
template <typename Arg, typename ... Args>
inline std::istream& read_fields(std::istringstream& line_stream, Arg& arg, Args&... args)
{
    if(line_stream >> arg)
        read_fields(line_stream, args...);
    return line_stream;
}

// Read and Skip Fields of a Line
template <typename ... Args>
std::istream& read_line(std::istream& stream, Args& ... args)
{
    std::string line;
    if(std::getline(stream, line)) {
        std::istringstream line_stream(line);
        read_fields(line_stream, args...);
        if(line_stream.fail()) {
            // Pass the fail state to the stream.
            stream.setstate(std::ios_base::failbit);
        }
    }
    return stream;
}

// Test
int main()
{
    std::string name;
    read_line(std::cin, name);

    std::string age;
    std::string weight;
    read_line(std::cin, age, weight);

    if(std::cin)
        std::cout << "Name: " << name << ", Age: " << age << "Weight: " << weight << '\n';
    else
        std::cout << "Failure\n";
    return 0;
}

Upvotes: 0

CS Pei
CS Pei

Reputation: 11047

I think you can just use

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

for example after cin >> name;.

Upvotes: 1

Related Questions