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

问题描述 投票:3回答:2

我正在学习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;
}

是否真的有必要经历接受字符串作为输入并将其转换为数字以执行计算的过程?

c++ getline
2个回答
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:如果您依赖用户最终只输入有效输入,那么您将被烧毁。以字符串形式读取和转换提供了一致的方法,以确保您只是从用户那里获得良好的输入。


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或其他解析细节。

© www.soinside.com 2019 - 2024. All rights reserved.