【发布时间】:2009-02-05 03:24:42
【问题描述】:
我想知道如何使用std::cin 将输入值限制为带符号的小数。
【问题讨论】:
标签: c++ visual-c++
我想知道如何使用std::cin 将输入值限制为带符号的小数。
【问题讨论】:
标签: c++ visual-c++
double i;
//Reading the value
cin >> i;
//Numeric input validation
if(!cin.eof())
{
peeked = cin.peek();
if(peeked == 10 && cin.good())
{
//Good!
count << "i is a decimal";
}
else
{
count << "i is not a decimal";
cin.clear();
cin >> discard;
}
}
这也给出了输入 -1a2.0 的错误消息,避免将 -1 分配给 i。
【讨论】:
discard 是什么? #2:为什么是10?麦克呢? #3:你如何形成一个循环来重试?当您编写它时,请尝试输入"ddd"。你会得到你的错误很多次。如果没有,那么我真的很好奇你的解决方案。
int peeked 吗? en.cppreference.com/w/cpp/io/basic_istream/peek 表示它返回一个字符或Traits:eof()。
如果cin的后备变量是数字,而提供的字符串不是数字,则返回值为false,所以需要循环:
int someVal;
while(!(cin >> someVal)) {
cin.reset();
cout << "Invalid value, try again.";
}
【讨论】:
输入.h
#include <ios> // Provides ios_base::failure
#include <iostream> // Provides cin
template <typename T>
T getValidatedInput()
{
// Get input of type T
T result;
cin >> result;
// Check if the failbit has been set, meaning the beginning of the input
// was not type T. Also make sure the result is the only thing in the input
// stream, otherwise things like 2b would be a valid int.
if (cin.fail() || cin.get() != '\n')
{
// Set the error state flag back to goodbit. If you need to get the input
// again (e.g. this is in a while loop), this is essential. Otherwise, the
// failbit will stay set.
cin.clear();
// Clear the input stream using and empty while loop.
while (cin.get() != '\n')
;
// Throw an exception. Allows the caller to handle it any way you see fit
// (exit, ask for input again, etc.)
throw ios_base::failure("Invalid input.");
}
return result;
}
用法
输入测试.cpp
#include <cstdlib> // Provides EXIT_SUCCESS
#include <iostream> // Provides cout, cerr, endl
#include "input.h" // Provides getValidatedInput<T>()
int main()
{
using namespace std;
int input;
while (true)
{
cout << "Enter an integer: ";
try
{
input = getValidatedInput<int>();
}
catch (exception e)
{
cerr << e.what() << endl;
continue;
}
break;
}
cout << "You entered: " << input << endl;
return EXIT_SUCCESS;
}
样品运行
输入一个整数:a
输入无效。
输入一个整数:2b
输入无效。
输入一个整数:3
您输入:3。
【讨论】:
cin 的 >> 运算符的工作方式是一次读取一个字符,直到遇到空格。这将吞噬整个字符串-1a2.0,这显然不是一个数字,因此操作失败。看起来您实际上有三个字段,-1、a 和 2.0。如果你用空格分隔数据,cin 将能够毫无问题地读取每一个数据。请记住为第二个字段阅读char。
【讨论】:
我尝试了许多技术来使用 >> 运算符从用户那里读取整数输入,但在某种程度上我的所有实验都失败了。
现在我认为 getline() 函数(不是 std::istream 上同名的方法)和 include cstdlib 中的 strtol() 函数是解决此问题的唯一可预测的一致解决方案。如果有人证明我错了,我将不胜感激。这是我使用的类似的东西:
#include <iostream>
#include <cstdlib>
// @arg prompt The question to ask. Will be used again on failure.
int GetInt(const char* prompt = "? ")
{
using namespace std; // *1
while(true)
{
cout << prompt;
string s;
getline(cin,s);
char *endp = 0;
int ret = strtol(s.c_str(),&endp,10);
if(endp!=s.c_str() && !*endp)
return ret;
}
}
using namespace whatever; 放置在全局范围内可能会导致大型项目的“统一构建”(google!)中断,因此应避免。练习不要使用这种方式,即使是在较小的项目中!cin 的同一程序中使用>> 和getline() 会导致一些问题。只使用其中一种,或者谷歌知道如何处理这个问题(不要太难)。【讨论】:
类似:
double a;
cin >> a;
应该阅读您签名的“十进制”罚款。
您需要一个循环和一些代码来确保它以合理的方式处理无效输入。
祝你好运!
【讨论】: