如何以及何时使用getline函数执行计算?

时间:2018-09-04 11:38:32

标签: c++ getline

我正在学习C ++课程,并被要求使用getline计算圆的面积。建议我不要使用cin,除非确实有必要。

下面是我的代码。

#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;
}

真的需要接受一个字符串作为输入并将其转换为数字以执行计算的过程吗?

2 个答案:

答案 0 :(得分:3)

  

真的需要接受一个字符串作为输入并将其转换为数字以执行计算的过程吗?

这不是严格必要的,但确实可以养成良好的习惯。假设您要向用户索取2个号码,并使用类似的

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

对于第一个数字,用户输入123boboperator>>将开始读取它,一旦它命中b,它将停止并将123存储到first_number中。现在,流中还有bob。当由于bob仍在流中而要求第二个数字时,它将失败并且second_number将被设置为0。然后程序将继续运行,并且由于您接受了垃圾输入,您将获得垃圾输出。

现在,如果您以std:string的身份读取然后转换为所需的内容,则可以更轻松地捕获这些类型的错误。 getline(std::cin, some_string);将从输入缓冲区中取出所有123bob,因此您不必担心必须清理它。然后使用stoi(或任何stox函数)将读取其中的有效值。这些函数还具有第二个参数,该参数是指向size_t的指针,如果将其传递给它,它将存储字符串中第一个未转换字符的位置,您可以使用该参数来判断整个输入字符串是否为有效与否。所以,如果你有

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";

然后1.23bob将导致invalid input打印,而1.23将导致valid input打印。您甚至可以在循环中使用它来确保仅获得有效输入,例如

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:如果您依靠用户仅输入有效输入,最终将被烧毁。作为字符串读入并进行转换提供了一种一致的方法,以确保您仅从用户那里获得良好的输入。

答案 1 :(得分:0)

  

我建议除非真的必要,否则不要使用cin。

首先,存在误解,因为您仍在使用std::cin。我将您的问题解释为使用std::cin::operator >>getline(std::cin,...)。接下来,我建议您采取相反的做法:如果可以,请直接使用operator>>,如果需要,请使用getline

一个非常人为的例子:

假设您以这种(不必要复杂的)格式将整数存储在文件中,

3123212
^-------- number of digits of the first number
 ^^^----- first number
    ^---- number of digits of the second number
     ^^-- second number

您不能使用裸露的std::cin >>来读取这些数字。相反,您需要阅读整行,然后解析数字。但是,即使如此,我还是强烈建议为operator>>提供重载,类似

struct NumbersReadFromStrangeFormat {
    std::vector<int> numbers;
};

std::isstream& operator>>(std::istream& in,NumbersReadFromStrangeFormat& num) {
    // use getline and parse the numbers from the string
    return in;
}

这样您就可以再次写:

NumbersReadFromStrangeFormat numbers;
std::cin >> numbers;

结论: 重载operator>>是从输入流中读取内容的理想方式。 “使用std::cin”或“使用getline”并不是真正的选择。 “避免使用std::cin”一定是一种误解。如果没有operator>>的重载已经满足您的需要,则您可以编写自己的并很好地隐藏任何getline或其他解析详细信息。