【问题标题】:Check if input is integer检查输入是否为整数
【发布时间】:2016-05-19 20:30:23
【问题描述】:

为了学习 C++,我正在翻译一个我用 Python 写的程序。

这是我写的

n = 0
while n < 2:
    try:
        n = int(raw_input('Please insert an integer bigger than 1: '))
    except ValueError:
        print 'ERROR!'

为了从用户那里得到一个大于1的整数。

这是我暂时用 C++ 写的:

int n = 0;
while (n < 2) {
    cout << "Please insert an integer bigger than 1: ";
    cin >> n;
}

我看了一下 try-catch ,它看起来很简单。我关心的是如何检查输入是否为整数。我阅读了有关 cin.fail() 的信息,但找不到任何官方文档,也没有真正了解它是如何工作的。

那么,如何检查输入是否为整数?

更一般地说,我如何检查输入是否为“anything”?

【问题讨论】:

标签: python c++ cin


【解决方案1】:

对于这种情况,您可能希望将输入读取为字符串,然后检查该字符串(例如,“仅包含数字,最多 N 位”)。当且仅当它通过检查时,解析出一个int

也可以将检查和转换结合起来——例如,Boost lexical_cast&lt;int&gt;(your_string) 将尝试从字符串中解析出一个 int,如果不能将整个内容转换为 int,则会抛出异常。

【讨论】:

  • @LogicStuff 测试流状态仅适用于某些场景。如果我在int 中输入15.30 cin 会很好,但流中仍然会留下.30
  • @LogicStuff:正如 Nathan 所暗示的,流状态告诉您输入数据是否以至少一个可以转换为正确类型的字符开头。在这种情况下,听起来(至少在我看来)他想检查 all 输入是否可以被转换。
  • @JerryCoffin:lexical_cast 安装在哪里?我在packages.ubuntu.com/… 中进行了搜索,但是当我尝试安装 libboost1.46-dev 和 libboost1.48 时,我得到了:E: Package 'libboost1.46(and 48)-dev' has no installation candidate
  • @JerryCoffin 哦,是的,但我想避免安装整个包
【解决方案2】:

如果您使用 C++11 的 std::stoi 结合 std::getline 读取整行输入,您的 Python 代码可以更直接地翻译。这比使用标准 I/O 错误处理要容易得多,标准 I/O 错误处理可以说没有非常用户友好的界面。

std::stoi 如果输入无法正确解析为整数,则抛出 std::invalid_argument,如果数字太小或太大而无法放入 int,则抛出 std::out_of_range

#include <iostream>
#include <string>

int main() {
    int n = 0;
    while (n < 2) {
        std::cout << "Please insert an integer bigger than 1: ";
        std::string input;
        std::getline(std::cin, input);
        try {
            n = std::stoi(input);
        } catch (std::exception const&) {
            std::cerr << "ERROR!\n";
        }
    }
}

如果你想让代码更类似于它的 Python 等效代码,那么你可以将输入封装在一个函数中:

#include <iostream>
#include <string>

int raw_input(std::string const& message)
{
    std::cout << message;
    std::string input;
    std::getline(std::cin, input);
    return std::stoi(input);
}

int main() {
    int n = 0;
    while (n < 2) {
        try {
            n = raw_input("Please insert an integer bigger than 1: ");
        } catch (std::exception const&) {
            std::cout << "ERROR!\n";
        }
    }
}

【讨论】:

  • 我有 2 个问题:1. 当我运行你的代码时,我得到 error: ‘stoi’ is not a member of ‘std’,2. 我不明白 raw_input 中 const&amp; message 和 catch 中 const&amp; 的含义。你能解释一下吗?
  • @Pigna:我猜你的编译器太旧了。升级以获得 C++11 支持。 const&amp; 表示“常量引用”。像这样传递不可修改的字符串是很常见的,以避免不必要的复制。然而,此类事情在介绍性 C++ 书籍中进行了处理。如果你对语言很认真,你需要通过书来学习。
  • 我不需要升级g++,我只需要添加--std=c++11。我对此很认真,我刚刚开始在learncpp.com上学习。但我更喜欢在完成课程之前弄脏自己的手。
  • 另一个问题@ChristianHackl:使用这些方法,如果我输入一个浮点数,它不会引发错误。如何解决这个问题?
  • @Pigna: std::stoi 非常宽松,如果在已经解析了正确的整数之后还有其他字符(例如"123xxx""123.001"),则默认情况下不会报告错误。为了解决这些情况,std::stoi 有第二个参数,它告诉您解析了多少个字符以获得结果。如果此数字不等于输入字符串的大小,则您知道字符串中存在其他字符。 size_t pos; int result = std::stoi(input, &amp;pos); bool error = (pos != input.size());
猜你喜欢
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
相关资源
最近更新 更多