Thread: make std::cin store more than 1 word in a string?

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    6

    make std::cin store more than 1 word in a string?

    While using "std::cin >> foo;" whenever the input includes a space, only the input before the space is stored in "foo"
    How can I store an entire sentence in "foo"?
    (foo is an object of type std::string)

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    The >> operator stops reading at any whitespace. If you want an entire line you should use getline instead:
    Code:
    std::getline(cin, foo);
    If you want a proper sentence rather than a line, the most obvious way is to read characters until you reach a punctuator:
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void get_sentence(string &s);
    
    int
    main()
    {
      string foo;
    
      get_sentence(foo);
      cout<< foo <<endl;
    }
    
    void
    get_sentence(
      string& s
      )
    {
      char   ch;
      string punct(".!?");
    
      while (cin.get(ch)) {
        s.push_back(ch);
        if (punct.find(ch) != string::npos) {
          break;
        }
      }
    }
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Oct 2003
    Posts
    6
    I used this code:
    Code:
    vector<string> question;
    cout << "Enter Question: ";
    std::getline(cin, input);
    question.push_back(input);
    cout << "debug: question entered.";
    When I run the program, the output is:
    Code:
    Enter Question: debug: question entered.
    Why?

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Why?
    Because the cin>>something doesn't play well with others. Most likely a call to cin's >> operator left a newline in the stream that your call to getline immediately terminated on, thinking that it was at the end of the line.

    The best way to fix the problem is to only use getline for input and then do conversions once you have a string. But, this is a more complex approach than using the >> operator, so you can "cheat" a little by eating the newline left over:
    Code:
    cin>> something;
    cin.ignore();
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Oct 2003
    Posts
    6
    Doesn't work, I still get the same output..
    What should I change in the code above to make it work?

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >What should I change in the code above to make it work?
    I don't know. You didn't give enough code for me to have a good idea of what your problem is.
    My best code is written with the delete key.

  7. #7
    Registered User
    Join Date
    Oct 2003
    Posts
    6
    Quote Originally Posted by Prelude
    >What should I change in the code above to make it work?
    I don't know. You didn't give enough code for me to have a good idea of what your problem is.
    Code:
    int main() {
       vector<string> question;
       cout << "Enter Question: ";
       std::getline(cin, input);
       question.push_back(input);
       cout << "debug: question entered.";
       vector<string> foo;
       cin >> foo;
    }
    When I run the program and give input with a space in it, the word coming after the space bleeds over into foo. That is, if I were to enter "one two" as the input, "question" would contain "one" and "foo" would contain "two"
    How do I make it so that "question" can contain spaces? (e.g. hold a phrase like "the dog slept")
    Last edited by pilot1; 05-19-2004 at 07:13 PM.

  8. #8
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Your posted code won't even compile, so it doesn't demonstrate the problem you are having very well. The code below compiles and works as you want it to:
    Code:
    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
       string input;
       cout << "Enter Question: ";
       std::getline(cin, input);
       cout << "debug: question entered: " << input << endl;
    
       string foo;
       cout << "Enter Question: ";
       cin >> foo;
       cout << "debug: question entered: " << foo << endl;
    }
    So either post more of your code or see if the above helps you solve it.

    Also, note that in Visual C++ 6.0 there is a bug in getline that might be causing you troubles. If you use VC++ 6 then go to http://www.dinkumware.com/vc_fixes.html and scroll down to the part referring to <string>.

  9. #9
    Registered User
    Join Date
    Oct 2003
    Posts
    6
    Sorry about that, I didn't realize the code wouldn't compile. I'm not using VC++ at all, so that's not the problem. Here's a chunk of code from my actual program.
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::vector;
    using std::cout;
    using std::cin;
    using std::string;
    
    int main()
    {
        int wordcount;
        cout << "How many questions? ";
        cin >> wordcount;
        vector<string> question;
        vector<string> answer;
        int i = 0;
        int x = 0;
        string input;
        while (i < wordcount) {
    	cout << "Enter Question: ";
    	cin >> input;
    	question.push_back(input);
    	cout << "input: " << question[x] << std::endl;
    	cout << "Enter Answer: ";
    	cin >> input;
    	answer.push_back(input);
    	cout << "input: " << answer[x] << std::endl;
    	x++;
    	i++;
        }
    }
    And here's what happens when I run it:
    How many questions? 3
    Enter Question: Multi Word Input
    input: Multi
    Enter Answer: input: Word
    Enter Question: input: Input
    Enter Answer: More Multi Word Input
    input: More
    Enter Question: input: Multi
    Enter Answer: input: Word

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    You're right back at the beginning again. Remember that cin>>something will stop reading at whitespace. If you want to read strings with whitespace you need to use getline. However, getline and cin>>something don't mix well because the latter will usually leave '\n' in the stream for getline to terminate immediately on. A quick way to avoid this is to call cin.ignore() after every cin>>something:
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::vector;
    using std::cout;
    using std::cin;
    using std::string;
    
    int main()
    {
      int wordcount;
      cout << "How many questions? ";
      cin >> wordcount;
      cin.ignore();
      vector<string> question;
      vector<string> answer;
      int i = 0;
      int x = 0;
      string input;
      while (i < wordcount) {
        cout << "Enter Question: ";
        getline(cin, input);
        question.push_back(input);
        cout << "input: " << question[x] << std::endl;
        cout << "Enter Answer: ";
        getline(cin, input);
        answer.push_back(input);
        cout << "input: " << answer[x] << std::endl;
        x++;
        i++;
      }
    }
    My best code is written with the delete key.

  11. #11
    Registered User
    Join Date
    Oct 2003
    Posts
    6
    Ohhh, cin.ignore(); goes BEFORE getline. When you suggested using cin.ignore at first, I was placing it after getline. Now it works.
    Thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  2. Replies: 7
    Last Post: 06-16-2006, 09:23 PM
  3. lvp string...
    By Magma in forum C++ Programming
    Replies: 4
    Last Post: 02-27-2003, 12:03 AM
  4. length of string etc.
    By Peachy in forum C Programming
    Replies: 5
    Last Post: 09-27-2001, 12:04 PM