C++ how to use getline -- Having issues with this program

  • Context: C/C++ 
  • Thread starter Thread starter needOfHelpCMath
  • Start date Start date
  • Tags Tags
    C++ Issues Program
Click For Summary
SUMMARY

The discussion focuses on reading a word and a number from user input in C++ using both the stream extraction operator and the getline() function. It establishes that using the extraction operator (>>) is sufficient for reading a single word and an integer, as it automatically handles whitespace. However, if getline() is used, the input must be parsed manually to separate the word from the number. The final solution provided utilizes string member functions such as find() and substr() to effectively extract the word and convert the number from a string to an integer.

PREREQUISITES
  • Understanding of C++ syntax and structure
  • Familiarity with string manipulation functions in C++
  • Knowledge of input/output operations in C++
  • Basic understanding of data types, specifically strings and integers
NEXT STEPS
  • Explore C++ string member functions such as find_first_not_of() and substr()
  • Learn about error handling for user input in C++
  • Investigate the differences between using getline() and the extraction operator (>>)
  • Practice parsing strings in C++ for various input formats
USEFUL FOR

C++ developers, programming students, and anyone looking to improve their skills in handling user input and string manipulation in C++.

needOfHelpCMath
Messages
70
Reaction score
0
A user types a word and a number on a single line. Read them into the provided variables. Then print: word_number. End with newline. Example output if user entered: Amy 5
Amy_5
Code:
#include <iostream>
#include <string>
using namespace std;

int main() {
   string userWord;
   int userNum = 0;
userWord="Amy";
cout << userWord;
getline(cin,userWord);
   return 0;
}
 
Last edited by a moderator:
Technology news on Phys.org
I don't see that you need getline() for this at all, only the stream extraction operator >>.

With a string variable, it skips any initial whitespace (blanks, tabs, newlines), then reads a single "word" (sequence of non-whitespace characters), stopping at the next whitespace character.

With a numeric variable, e.g. an int, it skips initial whitespace, then reads characters until it encounters a character that cannot be part of the number (e.g. whitespace).

Therefore the following code accomplishes the desired task:

C++:
#include <string>

using namespace std;

int main ()
{
    string userWord;
    int userNum = 0;

    count << "Please enter a (single) word and a number (integer)\n"
         << "separated by a space:" << endl;
    cin >> userWord >> userNum;
    count << userWord << '_' << userNum << endl;

    return 0;
}
 
But what if you're really supposed to use getline()?

C++:
    string userLine;
    getline (cin, userLine);

This reads the entire line at once, so that in your example, userLine contains the string "Amy 5". Now you need to parse the string, that is, split it up into "Amy" and "5", then convert the string "5" into the integer 5.

Here's one way to do it. The basic idea is to step through the line one character at a time, appending each blank character to userWord or userWord2, or skipping it.

C++:
//  Read non-blank characters and append them to userWord. Stop when we reach a blank.

    int pos = 0;
    while (userLine[pos] != ' ')
    {
        userWord += userLine[pos];
        ++pos;
    }

//  Skip over the blank space between "words"

    ++pos;

//  Append the remaining characters (until the end of the line) to userWord2, then
//  convert userWord2 to an int.

    string userWord2;
    while (pos < userLine.length())
    {
        userWord2 += userLine[pos];
        ++pos;
    }
    userNum = stoi (userWord2);  // standard function that converts string to int

This code also works if the number is longer than one digit. However, it doesn't anticipate some ways that the input could vary slightly. For example, what happens if there are blank spaces before the (first) word? I leave it as an exercise to fix this code so it takes this possibility into account. Also try to think up other situations like this, and fix them.
 
  • Like
Likes   Reactions: Greg Bernhardt
Plain old C has the required functions:
  • main( int argc, char *argv[ ], char *envp[ ] ) contains the number of parameters, and a pointer to a list of arguments
  • char *strtok(char *str, const char *delim) returns the "next" parameter from a string delimited by delim
Thus if argc equals 2, you can use printf("%s_%s", argv[1], argv[2]);
 
  • Like
Likes   Reactions: Greg Bernhardt
C++ strings do have member functions for manipulating them, so you don't have to do everything character by character. In particular we have

  • someString.find(whatever) which finds whatever (either a char or a string) in someString and returns its position
  • someString.substr(pos,nChars) which returns a substring of someString, specified by its location pos and length nChars
  • someString.length() which returns the number of characters contained in someString

These functions let us eliminate the fiddly character-loops in my previous solution.

C++:
#include <iostream>
#include <string>

using namespace std;

int main ()
{
    string userWord;
    int userNum = 0;

    count << "Please enter a (single) word and a number (integer)\n"
         << "separated by a space:" << endl;

    string userLine;
    getline (cin, userLine);

    int spacePos = userLine.find(' ');
    int word1Pos = 0;
    int word1Length = spacePos;
    userWord = userLine.substr (word1Pos, word1Length);

    int word2Pos = spacePos + 1;
    int word2Length = userLine.length() - word2Pos;
    string userWord2 = userLine.substr (word2Pos, word2Length);

    userNum = stoi (userWord2);

    count << userWord << '_' << userNum << endl;

    return 0;
}

Like my previous solution, this one also fails if the user enters spaces before the first word. To fix this problem, you can use a string member function someString.find_first_not_of(whatever) that finds the position of the first character that is not the specified one.

https://cplusplus.com/reference/string/string/find_first_not_of/

I also leave this as an exercise. Note that both find() and find_first_not_of() can be told to start their search at some location other than the beginning of the string: someString.find(whatever, startPos).
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
12K
  • · Replies 3 ·
Replies
3
Views
10K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 118 ·
4
Replies
118
Views
10K
Replies
12
Views
3K
  • · Replies 22 ·
Replies
22
Views
4K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 65 ·
3
Replies
65
Views
7K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 15 ·
Replies
15
Views
4K