【问题标题】:Disabling Implicit Casting in c++在 C++ 中禁用隐式转换
【发布时间】:2013-04-29 10:58:55
【问题描述】:

是否可以在 C/C++ 中禁用隐式转换。

假设我想写一个有效性函数,让我只输入integers in range [1,10]

我写过:

#include <iostream>


using namespace std;

int main( )
{
    int var=0;
    cout << "Enter a number (Integer between 1 to 10) : ";

    while( (!(cin >> var )) || (var > 10 ) || (var < 1) )
    {
        cout << "U nuts .. It can only be [1,10]\n";
        cin.clear();
        cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
        cout << "Enter a number (Integer between 1 to 10) : ";
        }

    cout << "\nYou entered : " << var;

   return 0;
}

但如果用户输入 9.5,它会通过将浮点数 9.5 转换为 9 并将其存储在 var 中来接受它。我希望任何浮动条目都被视为无效条目。我如何最紧凑地实现这一点。

我不想做这种事情:

#include <iostream>
#include <cmath>


using namespace std;

int main( )
{
    float var=0;
    cout << "Enter a number (Integer between 1 to 10) : ";

    while( (!(cin >> var )) ||(var < 1)|| (var > 10 ) || !(ceilf(var) == var) )
    {
        cout << "U nuts .. It can only be [1,10]\n";
        cin.clear();
        cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
        cout << "Enter a number (Integer between 1 to 10) : ";
        }

    cout << "\nYou entered : " << var;

   return 0;
}

这符合我的目的。但我想知道的是,有什么方法可以将 float 转换为 int - 我可以抑制或将其显示为错误输入。

类似于 cin &gt;&gt; var 的方式,其中 var 类型为 int - 如果我们输入 char 它会返回错误条件。我们可以为float 条目实现相同的目标吗?

谢谢

【问题讨论】:

  • 读取一个字符串并进行自己的转换。
  • @Koushik dude .. 看看这个 .. 你对 I/O 流类感到困惑 ...parashift.com/c++-faq-lite/istream-and-ignore.html
  • @sftrabbit 如果您输入任何字符 - 假设我输入 'j''hello' - 然后对于表达式 'cin &gt;&gt; var' 将设置返回的 istream&amp; 失败位 - 它评估为 @987654334 @ as var 类型为int
  • @Koushik 也检查this
  • 请注意,没有“隐式转换”之类的东西。 cast 是您在代码中编写的内容,用于告诉编译器进行 conversion隐式转换是编译器在没有强制转换的情况下进行的转换; 显式转换是编译器由于强制转换而执行的转换。

标签: c++


【解决方案1】:

但如果用户输入 9.5,它会通过将浮点数 9.5 转换为 9 并将其存储在 var 中来接受它。

不,它没有。如果用户输入9.5,则cin &gt;&gt; var 在遇到. 时停止读取(并将其留在流中)。没有浮点到整数的转换,因为你没有读过float,只是读了int

解决方法是读取输入的其余部分(在cin &gt;&gt; var 之后),并确保在int 结束后没有任何不好的东西。

【讨论】:

  • 检查 cin 流中残留字符的最佳方法是什么?有什么功能可以检查残差吗? cin 也总是让我感到困惑 - 假设它正在输入一个字符串.. 当我们点击 enter 时,它是保留在流中还是提取并保存在字符串 var str 中以用于表达式,例如 cin &gt;&gt; str
  • @GauravK 可以在您阅读 var 后尝试 cin.ignore
  • 添加到之前的评论:我的意思是问 - string str; cin &gt;&gt; str 现在我输入 hello 然后点击 enter - 这个 enter 是保留在流中还是也保存到strhello
  • @Koushik ignore 将丢弃残差,我想检查是否存在任何残差?如答案中所述-当我们输入 9.5 时,.5 将保留在 cin 流中-是否有任何方法可以检查 istream 类对象中的残差?
  • @GauravK:最好的方法是string str; readline(cin, str);。如果用户输入9 将读取一个空字符串,而cin &gt;&gt; str 将读取下一行。
【解决方案2】:

如果要验证所有输入,则必须先获取整行。

试试:

string line;
getline(cin, line); // gets whole line
char *endptr;
long int var = strtol(line.c_str(), &endptr, 10); // converts string to int

// now check that endptr points to end of the string
if (endptr<line.c_str()+line.length()) {
  // extra characters found after the integer
}

【讨论】:

  • 这取决于所需的行为,我无法确定这一点。 OP 将最有资格确定必要的调整,并且实现这一点并不难,因此我不会将此行为添加到答案中。
猜你喜欢
  • 1970-01-01
  • 2015-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多