我正在学习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 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:如果您依赖用户最终只输入有效输入,那么您将被烧毁。以字符串形式读取和转换提供了一致的方法,以确保您只是从用户那里获得良好的输入。
除非确实有必要,否则我被建议不要使用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
或其他解析细节。