c++ - 浮点输入中的 C++ 理解字符问题
问题描述
#include <iomanip>
#include <math.h>
int main() {
float x, a, b;
char conditions[] = { 'Y', 'y' };
std::cout << "Enter a number: ";
std::cin >> x;
if (!std::cin) {
std::cout << "error";
}
else {
a = x * x;
std::cout << "A is: " << a << std::endl;
}
}
//I need to create an if statement or a loop to
//ask to input float x again if char conditions were input instead.
我有一个问题几周来一直在寻找答案。从代码中您可以看到!std::cin
条件不接受任何字符,因此将打印错误。但是我需要一个例外,如果'y'
|| 'Y'
输入它会循环回到std::cin >> x;
并再次请求一个浮点值,直到它被提供,但是如果输入任何其他字符,'h'
它显然会返回错误消息。
我尝试了多个 if 语句,检查了递归但没有运气。问题是我不能例外,因为如果'y'
输入了,那么程序就无法理解它,因为它std::cin >>
要求的是一个数字而不是一个字符......
解决方案
任务描述不清楚。一方面,您声明您希望程序再次请求一个浮点值,直到提供一个。另一方面,您声明这只应该在用户输入"y"
or时发生"Y"
,但是当用户输入其他任何内容时,它应该打印一条错误消息。这是矛盾的。
如果您希望您的程序检查用户是否输入了某个字符,那么您必须将输入读取为字符串,而不是数字。我建议您使用std::getline
它。
一旦确定用户没有输入"Y"
or "y"
,就可以使用该函数std::stof
将字符串转换为数字。
当用户不输入数字时,我不明白您为什么说要循环回到 and 上的输入"y"
,"Y"
而是想在所有其他输入上打印错误消息。但是,如果这是您想要的,那么您可以通过以下方式实现它:
#include <iostream>
#include <string>
int main()
{
std::string input;
float x;
for (;;) //infinite loop, equivalent to while(1)
{
//prompt user for input
std::cout << "Enter a number: ";
//read one line of input
std::getline( std::cin, input );
if ( !std::cin )
throw std::runtime_error( "unexpected stream error!" );
//check if "y" or "Y" was entered
if ( input == "y" || input == "Y" )
continue;
//attempt to convert input to a number
try
{
x = std::stof( input );
}
catch ( std::invalid_argument )
{
printf( "Unable to convert to number\n" );
break;
}
catch ( std::out_of_range )
{
printf( "Number is out of range\n" );
break;
}
std::cout << "You entered the following number: " << x << "\n";
}
}
该程序按预期工作(基于您的矛盾描述)。如果输入"y"
or "Y"
,它将循环回到提示用户输入:
Enter a number: y
Enter a number: y
Enter a number: y
Enter a number: 67.5
You entered the following number: 67.5
"y"
如果您改为提供不是or的非数字输入"Y"
,它将打印一条错误消息,而不是循环回输入:
Enter a number: y
Enter a number: y
Enter a number: j
unable to convert to number
这种行为没有意义,但它似乎是你所要求的。
不过,这个程序确实有一个小问题。它将接受6sdfjloj
作为数字的有效输入6
:
Enter a number: 6sdfjloj
You entered the following number: 6
使用错误消息拒绝此类输入可能更有意义。
也可以这样做,通过将第二个参数传递给std::stof
,以确定转换了多少字符。如果不是所有字符都被转换,您可以拒绝输入。另一方面,您可能希望接受尾随空白字符(由 确定std::isspace
),但如果有任何其他尾随字符,则拒绝输入。这是有道理的:因为std::stof
接受前导空格字符,所以也接受尾随空格字符是有意义的。
在我看来,通过以下任务展示这些编程可能性会更有意义:
应改为使用以下消息提示用户:
"Please enter a number, or enter "q" to quit: "
如果用户输入"q"
或"Q"
,程序应该退出。
否则,它应该确定用户是否输入了有效的数字。如果输入是一个有效数字,程序应该这样说并打印该数字,否则它应该打印一条错误消息。无论哪种方式,程序都应该循环回到初始提示。
这个问题的解决方案如下:
#include <iostream>
#include <string>
#include <cctype>
int main()
{
std::string input;
float x;
std::size_t pos;
for (;;) //infinite loop, equivalent to while(1)
{
//prompt user for input
std::cout << "Please enter a number, or enter \"q\" to quit: ";
//read one line of input
std::getline( std::cin, input );
if ( !std::cin )
throw std::runtime_error( "unexpected stream error!" );
//check if "q" or "Q" was entered
if ( input == "q" || input == "Q" )
{
std::cout << "Quitting program!\n";
break;
}
//attempt to convert input to a number
try
{
x = std::stof( input, &pos );
}
catch ( std::invalid_argument )
{
printf( "Unable to convert to number!\n" );
continue;
}
catch ( std::out_of_range )
{
printf( "Number is out of range!\n" );
continue;
}
//make sure that any trailing characters are whitespace,
//otherwise reject input
for ( std::size_t i = pos; input[i] != '\0'; i++ )
{
if ( !std::isspace( static_cast<unsigned char>(input[i]) ) )
{
std::cout << "Unexpected character encountered!\n";
//we cannot use continue here, because that would jump
//to the next iteration of the innermost loop, but we
//want to jump to the next iteration of the outer loop
goto continue_outer_loop;
}
}
std::cout << "Input is valid, you entered the following number: " << x << "\n";
continue_outer_loop:
continue;
}
}
该程序具有以下输出:
Please enter a number, or enter "q" to quit: 67.5
Input is valid, you entered the following number: 67.5
Please enter a number, or enter "q" to quit: 32.1
Input is valid, you entered the following number: 32.1
Please enter a number, or enter "q" to quit: sdfjloj
Unable to convert to number!
Please enter a number, or enter "q" to quit: 6sdfjloj
Unexpected character encountered!
Please enter a number, or enter "q" to quit: q
Quitting program!
如您所见,它现在也正确拒绝输入,例如6sdfjloj
.
请注意,该程序包含一个goto
语句。为了跳出嵌套循环,使用它是合适的。这被认为是可接受的使用goto
. goto
但是,除非在没有更清洁的替代方案的极少数情况下,否则不应使用。所以请不要习惯使用它。
推荐阅读
- jupyter-notebook - OSX 10.13.6 KernelRestarter:重新启动内核
- php - 获取两个不同mysql表的结果
- batch-file - 批量复制重命名,重复时提示
- amazon-web-services - AWS CodePipeline - 用于后端服务和客户端 (Angular)
- python - 将字符串转换为浮点数麻烦python
- wix3.5 - 将参数从 msi 传递到 boostrap 包
- mysql - MySQL - 用数字按字母顺序排序
- plot - 在 Julia 中为 Agents.jl 制作 Makie.jl 情节配方动画的优雅方法是什么?
- python - Python - 连续打开文件的问题。权限错误[13]
- c++ - 如何修复抗锯齿系统的打印屏幕?