Search code examples
c++getline

How and when to use the getline function to perform calculations?


I am taking a course on C++ and I have been asked to compute the area of a circle by using getline. I was advised to refrain from using cin unless it is really necessary.

Below is my code..

#include <iostream>
#include <string>

int main()
{
    std::string question ("Enter the radius: ");
    std::string s_radius;
    std::cout << question;

    getline(std::cin, s_radius);

    const double PI = 3.14159;
    double n_radius = std::stod(s_radius);
    double area = PI * n_radius * n_radius;

    std::cout << "The area of the circle = " << area << std::endl;

    return 0;
}

Is it really necessary to go through the process of accepting a string as input and convert it to a numeral to perform the calculation?


Solution

  • Is it really necessary to go through the process of accepting a string as input and convert it to a numeral to perform the calculation?

    It isn't strictly necessary but it does enforce good habits. Let's assume you are going to ask for 2 numbers from the users and use something like

    std::cout << "Enter first number: ";
    std::cin >> first_number;
    std::cout << "Enter second number: ";
    std::cin >> second_number;
    

    For the first number the user enters 123bob. operator>> is going to start reading it in and once it hits b it is going to stop and store 123 into first_number. Now the stream has bob still in it. When it asks for the second number since bob is still in the stream it will fail and second_number will get set to 0. Then the program will continue on and you will get garbage output because you accepted garbage input.

    Now, if you read in as a std:string and then convert to what you want it makes it easier to catch these types of errors. getline(std::cin, some_string); would get all of 123bob out of the input buffer so you don't have to worry about having to clean it up. Then using stoi (or any of the stox functions) it will read the valid value of of it. The functions also have a second parameter which is a pointer to a size_t and if you pass it one it will store the position of the first unconverted character in the string and you can use that to tell if the entire input string is valid or not. So, if you had

    std::string input;
    std::cout << "Enter some number: ";
    std::getline(std::cin, input);
    std::size_t pos;
    double number = std::stod(input, &pos);
    if (pos == input.size())
        std::cout << "valid input\n";
    else
        std::cout << "invalid input\n";
    

    Then 1.23bob would cause invalid input to print where 1.23 cause valid input to print. You could even use this in a loop to make sure you get only valid input like

    double number;
    do
    {   
        std::string input;
        std::cout << "Enter some number: ";
        std::getline(std::cin, input);
        std::size_t pos;
        number = std::stod(input, &pos);
        if (pos != input.size())
            std::cout << "invalid input\n";
        else
            break;
    } while(true)
    

    TL;DR: If you rely on the user to only input valid input eventually you are going to get burned. Reading in as a string and converting offers a consistent way to ensure that you are only getting good input from your user.