如何以及何时使用 getline 函数执行计算?
How and when to use the getline function to perform calculations?
我正在上一门关于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;
对于第一个数字,用户输入123bob
。operator>>
将开始读取它,一旦它击中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
或其他解析细节。
- 如何以及何时使用 getline 函数执行计算?
- 主函数执行时C++堆栈溢出异常
- 如何编写在函数执行过程中垃圾回收的测试用例?
- 插入到映射中的元素在函数执行后清除
- 遵循 C++ 中的构造函数执行顺序
- 成员函数执行时成员变量的增量
- 关于如何在函数执行后使用和获取返回值的问题
- 从 C 代码 system() 函数执行的 Linux 命令与从终端执行时给出的结果不同
- 顺序异构函数执行器
- 静态 LPTSTR 变量在函数执行后丢失值
- C++如何使函数执行得更快
- C 中函数执行的优先顺序
- 函数执行时间
- 当类成员函数执行时,程序停止工作
- 主函数执行之前的C++segfault
- 如何使用以查看<chrono>函数执行所花费的时间
- 如何从另一个函数执行一个函数
- 函数执行一次
- 为我自己的函数执行通常的算术转换
- 如何对继承构造函数执行正确的SFINAE