简体   繁体   English

在C ++中检查合法的整数输入

[英]Checking for legitimate integer input in c++

so i've seen many people ask this and not many solid answers floating around the web. 因此,我已经看到很多人问这个问题,并且网上没有很多可靠的答案。 most just check that an integer was placed in place of a string but if a floating point number was entered then it truncates the bottom half or if integers and characters are intered it truncates the characters. 最简单的方法是检查是否已将整数替换为字符串,但是如果输入了浮点数,则它将截断下半部分,或者如果插入整数和字符,则将截断字符。 i need help writing a piece of code that checks for user input and asks the user to retry if his input is not valid or a combination of valid/invalid. 我需要帮助编写一段代码来检查用户输入,并要求用户重试他的输入无效或有效/无效的组合。 i think the basic idea was to make a string so it accepts anything then use sstream to manipulate and then back to int if the input was legit but i cant really manage to check the other parts. 我认为基本思想是制作一个字符串,以便它接受任何内容,然后使用sstream进行操作,如果输入合法,然后返回int,但我无法真正检查其他部分。 if anyones run accross this or can help me out please link me to it. 如果有人遇到这个问题或可以帮助我,请联系我。 i'll post my code when i get a good sense of what to do. 当我对要做什么有很好的了解时,我将发布我的代码。

Assuming that you can't use boost::lexical_cast , you can write your own version: 假设您不能使用boost::lexical_cast ,则可以编写自己的版本:

#include <sstream>
#include <iostream>
#include <stdexcept>
#include <cstdlib>
template <class T1, class T2>
T1 lexical_cast(const T2& t2)
{
  std::stringstream s;
  s << t2;
  T1 t1;
  if(s >> std::noskipws >> t1 && s.eof()) {
    // it worked, return result
    return t1;
  } else {
    // It failed, do something else:
    // maybe throw an exception:
    throw std::runtime_error("bad conversion");
    // maybe return zero:
    return T1();
    // maybe do something drastic:
    exit(1);
  }
}



int main() {
  std::string smin, smax;
  int imin, imax;

  while(std::cout << "Enter min and max: " && std::cin >> smin >> smax) {
    try {
      imin = lexical_cast<int>(smin);
      imax = lexical_cast<int>(smax);
      break;
    } catch(std::runtime_error&) {
      std::cout << "Try again: ";
      continue;
    }
  }

  if(std::cin) {
    std::cout << "Thanks!\n";
  } else {
    std::cout << "Sorry. Goodbye\n";
    exit(1);
  }
}

You can use C++11 string conversion functions like stol 您可以使用诸如stol之类的C ++ 11 字符串转换函数

try
{
    std::string value = ...;
    long number = std::stol(value); 
}
catch (std::invalid_argument const& e)
{
    // no conversion could be performed
}

Post-comments update: Visual C++ 11 shipped with Visual Studio 2012 implements std::stol as a convenient wrapper around strtol declared in <cstdlib> . 评论后更新:Visual Studio 2012附带的Visual C ++ 11将std::stol实现为<cstdlib>声明的strtol的便捷包装。 I think it's safe to assume most C++11 implementations define it in most optimal way possible, not reaching for std::stringstream machinery. 我认为可以安全地假设大多数C ++ 11实现以最佳的方式定义它,而不是使用std::stringstream机制。

The C function strtol (and it's siblings) will be able to tell you if the string fed to it is completely consumed. C函数strtol (及其兄弟姐妹)将能够告诉您输入给它的字符串是否被完全消耗。

 std::string str;
 char *endptr;
 std::cin >> str;
 long x = std::strtol(str.c_str(), &endptr, 0); 
 if (*endptr != 0) 
    cout << "That's not a valid number...";

I don't know if there are any classes in standard c++ lib that encapsule primitive types like in java but here how a simple and very basic implementation would look like 我不知道标准c ++ lib中是否有像Java这样的封装原始类型的类,但是在这里,简单而非常基本的实现是什么样的

class Integer {
   private:
       int value;
       void parse(string);
   public:
       Integer(string);
       int intValue();
};

Integer::Integer(string sint) { parse(sint); }
int Integer::intValue() { return value; }

void Integer::parse(string sint) {
    string::iterator its = sint.begin();
    while(its != sint.end() && (! (*its < '0' || *its > '9'))) {
        its++;
    }
    if(its != sint.end()) {
        throw sint + ": Input is not a valid integer.";
    }
    value = atoi(sint.c_str());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM