【问题标题】:C++ syntax question: if var != type intC++ 语法问题:if var != type int
【发布时间】:2010-11-28 22:43:18
【问题描述】:

我正在尝试编写 if 语句,但找不到要使用的正确表达式形式。我正在考虑写这样的东西:

if ( var != type(int) )

但是,我不确定该怎么做,而且这种方法不起作用。

我的想法至少是正确的吗?

【问题讨论】:

  • if 语句的主体是什么? (换句话说,您避免尝试使用 int 做什么?)
  • int n; if (cin >> n) { ... } 如果你进入 if 语句,那么你知道你的变量 n 是从字符串正确转换的。在 C++ 中,类型在编译时是已知的,所以你的问题有点奇怪。
  • 也许这有助于澄清,因为您似乎熟悉 Python:在 Python 和 C++ 中,当您读取输入时,您将其读取为字符串。然后,您必须将该字符串转换为整数。您的问题是您想确定该转换是否成功。关键是,在 C++ 中,由于您已将 var 声明为整数,因此它将始终是整数。从字符串到整数的转换是否成功都没有关系,var 无论如何都是整数。这有意义吗?
  • 感谢丹尼尔澄清这个问题。

标签: c++ integer types


【解决方案1】:

听起来你想重载一个函数:

void foo(int i)
{
    // stuff
}

void foo(float f)
{
    // stuff
}

int main(void)
{
    int i = 10;
    float f = 1.0f;

    foo(i); // calls foo(int)
    foo(f); // calls foo(float)
}

如果您想要int-特殊行为,然后在所有其他情况下需要其他行为,您可以使用模板:

template <typename T>
void foo(T t)
{
    // T is something
}

template <>
void foo(int i)
{
    // for int's only
}

int main(void)
{
    int i = 10;
    float f = 1.0f;
    double d = 2.0;

    foo(i); // calls specialized foo
    foo(f); // calls generic foo
    foo(d); // calls generic foo
}

根据您的评论(“手头的任务是一个简单的程序:获取两个用户输入的整数并将它们相加。将输入限制为仅整数。我可以在 Python 中做到这一点,我也在沿着这些思路思考。 if num1 != type(int): print "You didn't enter an integer, please enter a integer." else: continue"),你想要这样的:

#include <iostream>

int main(void)
{
    int i;
    std::cin >> i;

    if (std::cin.fail())
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

这将通知诸如“@#$”、“r13”之类的无效输入,但不会捕获诸如“34fg”、“12$#%”之类的情况,因为它会读取int,分别停在“fg”和“$#%”。

要检查这一点,您必须读入一行输入,然后尝试将该行转换为您想要的类型。 (谢谢,litb)。这意味着您的问题更多like this question

#include <iostream>
#include <sstream>
#include <string>

int main(void)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    int i;
    ss >> i;

    if (ss.fail() || !(ss >> std::ws).eof())
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

它执行以下操作:获取输入,并将其放入stringstream。然后在解析int 之后,流出任何剩余的空白。之后,如果eof 为假,则表示有剩余字符;输入无效。

这更容易使用包装在一个函数中。在另一个问题中,演员阵容被重新考虑了。在这个问题中,我们使用演员表,但将输入与它一起包装。

#include <iostream>
#include <sstream>
#include <string>

bool parse_int(int& i)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    ss >> i;

    return !(ss.fail() || !(ss >> std::ws).eof());
}

int main(void)
{
    int i;

    if (!parse_int(i))
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

或更笼统地说:

#include <iostream>
#include <sstream>
#include <string>

template <typename T>
bool parse_type(T& t)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    ss >> t;

    return !(ss.fail() || !(ss >> std::ws).eof());
}

int main(void)
{
    int i;

    if (!parse_type(i))
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

这让您可以通过错误检查解析其他类型。


如果您可以接受异常,使用 lexical_cast(来自 boost 或“伪造”,请参阅代码中链接的另一个问题 [与上述链接相同]),您的代码将如下所示:

#include <iostream>
#include <sstream>
#include <string>

/* Faked lexical-cast from question:
https://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
    std::stringstream ss(s);

    T result;
    if ((ss >> result).fail() || !(ss >> std::ws).eof())
    {
        throw std::bad_cast("Bad cast.");
    }

    return result;
}


template <typename T>
T parse_type(void)
{
    std::string input;
    std::getline(std::cin, input);

    return lexical_cast<T>(input);
}

int main(void)
{
    try
    {
        int i = parse_type<int>();
        float f = parse_type<float>();
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}

我认为 boost 没有词法转换的无抛出版本,因此我们可以通过捕获 bad_cast 来制作此代码的真/假而不是异常版本,如下所示。再一次,这适用于 boost 或自定义词法转换。 (任何进行词法转换并抛出 bad_cast 的东西):

#include <iostream>
#include <sstream>
#include <string>

/* Faked lexical-cast from question:
https://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
    std::stringstream ss(s);

    T result;
    if ((ss >> result).fail() || !(ss >> std::ws).eof())
    {
        throw std::bad_cast("Bad cast.");
    }

    return result;
}


template <typename T>
bool parse_type(T& t)
{
    std::string input;
    std::getline(std::cin, input);

    try
    {
        t = lexical_cast<T>(input);

        return true;
    }
    catch (const std::bad_cast& e)
    {
        return false;
    }
}

int main(void)
{
    int i;
    if (!parse_type(i))
    {
        std::cout << "Bad cast." << std::endl;
    }
}

现在返回到 bool 结果,除了我们通过使用现有的 lexical_cast 函数来避免代码重复。

您当然可以选择您想使用的方法。

【讨论】:

  • 我想知道至少有人能回答这个问题,至少对我来说是个难以理解的问题! +1 努力!!!
  • 这更有意义。 ws的添加也很棒。
  • 谢谢。请记住,就像其他人一直在说的那样,C++ 是强类型的。这些都是从字符串流到相应类型的转换。
  • 您的示例中的返回语句非常详尽。为什么不这样做:返回 std::cin >> t;
  • std::ws 方法适用于 stringstream,但无法适用于连接到终端的 std::cin。当你按下enter 时它会等待,吃掉它,直到你输入一些非空格并再次按下回车。当使用std::ws方式时,我总是将整行读入一个字符串,然后在stringstream上做剩余的工作。
【解决方案2】:

C++ 是一种静态类型语言,这意味着编译器始终知道变量的类型。因此,为了声明 var,您必须为其指定一个类型,这使得您发布的 if 语句成为一个有争议的问题。如果您能多描述一下您正在尝试完成的任务,也许还有其他方法可以解决您的问题。

【讨论】:

  • 手头的任务是一个简单的程序:取两个用户输入的整数并将它们相加。仅将输入限制为整数。我可以在 Python 中做到这一点,我也在沿着这些思路思考。 if num1 != type(int): print "You didn't enter an integer, please enter a integer."其他:继续
  • 在这种情况下,我想您想问一个问题,“如何确保来自用户的输入限制为整数”?在 C++ 中,有几种方法可以从用户那里获取输入,并且每种方法都有用于验证您获得的用户数据的技术。此外,在问题正文中包含更多您编写的代码也会有所帮助。
  • 您无需担心在运行时将输入类型限制为整数。像: int n;辛 >> n;确保 n 始终为整数。
  • True- 但我不熟悉 OP 如何从用户那里获取输入。例如,如果他们使用 getline,他们必须自己验证数据。鉴于您的示例,您的观点仍然有效。
  • @SD:通常,你应该问“如何解决这个问题”,而不是“如何让这个尝试奏效”。根据您上面的评论,我认为可以肯定地说您走错了路。 (事实上​​,那条轨道在错误的星球上。)在 C++ 中,为了获得正确类型的输入,人们使用流。我建议你再问一个问题,陈述你的问题并寻求解决方法。
【解决方案3】:

没错,需要更多信息,如果您正在寻找相当于 Java 的“instanceOf”运算符,则没有,除非您使用 RTTI 和 typeid。

【讨论】:

    【解决方案4】:

    你的意思是你有一个浮点值并且想知道它是否是一个整数?

    在这种情况下,试试这个:

    #include <math.h>
    
    //...
    
    double x = 5.0;
    if(round(x) == x) {
       // x has an integer value
    }
    

    或者,如果该值是某些计算的结果,则可能存在小的舍入误差。然后尝试这样的事情:

    double x = 4.99999999999;
    if(abs(round(x) - x) < 1e-8)
    

    【讨论】:

      猜你喜欢
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多