C++ 测试输入是不是为双精度/字符

Posted

技术标签:

【中文标题】C++ 测试输入是不是为双精度/字符【英文标题】:C++ test if input is an double/charC++ 测试输入是否为双精度/字符 【发布时间】:2022-01-11 07:13:35 【问题描述】:

我正在尝试从用户那里获取输入,并且需要知道一种让程序识别输入不是双/char的方法我现在拥有的...但是当您输入不正确的输入类型时

1) 双重测试只是无限循环

2) 即使输入正确,字符也不会停止循环

int main () 
    double _double = 0;
    bool done = true;
while ( done ) 
    cout << "Please enter a DOUBLE:\n" << endl;
    cin >> _double;
    if ( _double > 0 )  done = false; 
    if ( _double < 0 )  cout << "\nthe number you entered was less than zero\nplease enter a valad number..." << endl;  
    if(cin.fail())  cin.clear(); 


done = false;
char _char = ' ';
while ( !done ) 
    cout << "Please enter a CHAR" << "\n";
    cout << "\t'y' = yes\n\t'n' = no" << endl;
    cin >> _char;
    if ( _char == 'y' || _char == 'n' )  done = true; 
    if ( ! (_char == 'y' || _char == 'n') )  cout << "\nyou have entered an invald symbol... \n" << endl; 
    if(cin.fail())  cin.clear(); 

【问题讨论】:

它不起作用?您能否指定输出和预期输出?它可以让您更快地得到答案。 显然,您输入的任何字符都是字符。那个测试怎么可能失败?该代码表明您正在寻找一个 specific 字符,特别是 'y''n' 【参考方案1】:

最好的办法是始终将您的输入读取为字符串。然后,您可以使用 std::strtod() 之类的函数来测试并转换为双精度。检查流是否失败然后重置它们充其量是容易出错的,并且不会让您产生良好的错误消息。

例如:

string s;
cin >> s;
char * p;
double d = strtod( s.c_str(), & p );
if ( * p == 0 ) 
   cout << "Read double: " << d << endl;

else 
   cout << "Read string: " << s << endl;

指针“p”将指向第一个不能转换为双精度的字符。你如何处理这真的取决于你的应用程序的逻辑。

【讨论】:

【参考方案2】:

问题在于,当您读取某些内容并且cin 看到输入永远不会是双精度时,它会停止读取,将内容留在它没有消耗的缓冲区中。它会发出失败的信号,你可以清除它,但你不会吃掉cin 没有吃掉的剩余输入。所以,下次再次尝试读取相同的错误输入时,一次又一次......

char 的问题是您必须按回车键才能使其处理大多数终端上的任何字符(例如,如果您让程序从文件中读取,则不会发生这种情况)。因此,如果您按y,那么它不会退出读取调用,直到您按下返回键。但是,它通常会继续并退出循环。

正如其他人所说,您最好阅读整行,然后决定要做什么。您还可以使用 C++ 流而不是 C 函数来检查数字:

bool checkForDouble(std::string const& s) 
  std::istringstream ss(s);
  double d;
  return (ss >> d) && (ss >> std::ws).eof();

这会读取任何初始双精度数,然后读取任何剩余的空格。如果它然后点击eof(文件/流的结尾),这意味着字符串只包含一个双精度。

std::string line;
while(!getline(std::cin, line) || !checkForDouble(line)) 
  std::cout << "Please enter a double instead" << std::endl;

对于字符,你可以只测试长度 1

std::string line;
while(!getline(std::cin, line) || line.size() != 1) 
  std::cout << "Please enter a double instead" << std::endl;

如果您想只读取 1 个字符并在输入该字符后立即继续,那么您将不得不使用平台相关函数(C++ 不会将它们作为标准函数提供)。例如,请注意 Windows 的 conio.h 文件,该文件具有 _getch 函数。在 unix 系统上,ncurses 提供了这样的功能。

【讨论】:

哇'Johannes Schaub - litb',非常感谢!你不知道你为我节省了多少时间。谢谢!【参考方案3】:

cin &gt;&gt; _double 总是会给你加倍,无论他们输入“42”、“0”还是“mary had a little lamb”。您需要将用户输入读取为字符串,然后测试该字符串以查看它是否为双精度。如果 sscanf 无法将输入字符串转换为所需的类型,它将返回 0:

cout << "Please enter a DOUBLE:\n" << endl;
    string s;
cin >> s;
    if( !sscanf(s.c_str(), "%lf", &_double) )
    
        done = false;
        cout << "Not a number, sparky. Try again." << endl;
        continue;
    

此外,像您这样带有前导下划线的标识符是由语言保留的。不要养成命名 _double 之类的习惯——总有一天,它们可能不起作用。

【讨论】:

哈哈是的,'_'只是为了给出一个更简洁的来源示例 其实可以测试cin &gt;&gt; _double的结果:if(cin &gt;&gt; _double) done=true; else cout &lt;&lt; "Not a number!" &lt;&lt; endl; 格式说明符错误,必须是“%lf”。使用 "%f" 将浮点数填充为双精度数。这有点像两者中最糟糕的。

以上是关于C++ 测试输入是不是为双精度/字符的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中将字符串转换为双精度值?

将字符串转换为双精度 [重复]

将字符串转换为双精度的 C++ 错误

C++ 将字符串转换为双精度

在 C++ 中将字符串转换为双精度

如何使用 stringstream 在 C++ 中将字符串转换为双精度值 [关闭]