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

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

本文关键字:函数 执行 计算 getline 何时使      更新时间:2023-10-16

我正在上一门关于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 个数字并使用类似

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 inputn";
else
std::cout << "invalid inputn";

然后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 inputn";
else
break;
} while(true)

TL;DR:如果你依赖用户只输入有效的输入,你最终会被烧毁。作为字符串读入和转换提供了一种一致的方式来确保您只从用户那里获得良好的输入。

除非真的有必要,否则建议我不要使用 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或其他解析细节。