English 中文(简体)
我如何测试输入数据总是处于分类类型?
原标题:How can I test the input data are always integer type?
  • 时间:2012-01-16 08:28:44
  •  标签:
  • c++
  • vector

if I want to test my input data are always integer, how can I do? I mean I want to put the input into the vector, but I want to make sure the inputs are integer. I know when I type such as "A" it will jump out the while loop. But I wish it can be more elegance, how can I do for this. Any suggestion? ps: I don t want to use char to test and convert.

这里是简单的法典。 感谢很多。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
vector<int> ivec;
int num;

cout << "Please enter some integers for input or (exit) to exit" << endl;

while(cin >> num)
{
    ivec.push_back(num);
}
.....
问题回答

这取决于你是否希望重新发明轮轮椅,或者如果你愿意站在巨头的肩上。

在后一种情况下,我只能建议<代码>boost:lexical_cast<T>。

#include <iostream>
#include <string>
#include <vector>

#include <boost/lexical_cast.hpp>

int main() {
  std::string buffer;
  std::vector<int> vec;

  std::cout << "Please enter an integer:" << std::endl;
  while (true) {
    std::cin >> buffer;

    try {
      vec.push_back(boost::lexical_cast<int>(buffer));
      break; // exit the loop
    } catch(boost::bad_lexical_cast const&) {}

    std::cout << "Sorry,  "
              << buffer
              << "  could not be parsed as an integer, please try again."
              << std::endl;
  }

  return vec.size() == 1;
}

有一种内在功能线,将一个果园变成了愤怒。 然而,有3个优势案例:

  • 如果改划不成功,则将退回0,这样,当2起案件被退回时,你应加以区别。

  • 如果ger升值太大, 页: 1

  • 如果ger升值太小,则送回MIN

正因为如此,我更倾向于修改这一条,处理这些案件:

bool safe_atoi(const char* str, int *value) {
  *value = atoi(str);
  if (*value == 0) {
    return str[0] ==  0  && str[1] == 0;
  }

  if (*value != INT_MAX && *value != INT_MIN) {
    return true;
  }

  if (*value == INT_MAX) {
    char buf[12];
    sprintf(buf, "%d", INT_MAX);
    return strncmp(buf, str, strlen(buf)) == 0;
  }

  if (*value == INT_MIN) {
    char buf[12];
    sprintf(buf, "%d", INT_MIN);
    return strncmp(buf, str, strlen(buf)) == 0;
  }

  return false;
}

之后,你可以发挥这一作用,实现你想要的东西:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main()
{
  vector<int> ivec;
  int num;

  cout << "Please enter some integers for input or (exit) to exit" << endl;

  string input;

  while(cin >> input)
  {
    if (safe_atoi(input.c_str(), &num)) {
      ivec.push_back(num); 
    } else {
      // handle that case
    }
  }

You could also try regular expressions. In C++11:

#include <iostream>
#include <regex>
#include <string>

using namespace std;

int main()
{
    string input;
    regex integer("(\+|-)?[[:digit:]]+");
    //As long as the input is correct ask for another number
    while(true)
    {
        cout<<"Give me an integer!"<<endl;
        cin>>input;
        //Exit when the user inputs q
        if(input=="q")
            break;
        if(regex_match(input,integer))
            cout<<"integer"<<endl;
        else
        {
            cout<<"Invalid input"<<endl;
        }
    }
}

这方面的例子见here,充分计入作者。 如果您的汇编者不支持C++11的定期表述,boost.regex是你的下一个最佳选择。 这是一种非常沉重的关税解决办法,但是,这种解决办法可以用于其他类型的投入。

参看守则实例,这是这样做的三种共同方法。 首先,只要我们有有效的愤怒,我们就可以选择读写:这是比较容易的办法。 (要求包括:推定在场)

int main() {
    std::vector<int> values;
    int i;
    while((std::cout << "Enter a number: ") && (std::cin >> i))
        values.push_back(i);
    // We ve finished reading all values we could, let s work on them.
}

这种做法既简短又简单,让用户继续进入“exit”,或者实际上不会有数量的东西。 这样做的好处是,你可以将档案转至档案中,在档案结尾处必须“挖掘”(EOF将正确终止该档案)。 然而,这意味着,出现错误的用户不能再输入任何数据。

或者,你们也可以使用类似的东西,读到上游结束之前,然后在此之后 exception一个例外。 这并非特别令人痛心:作为正常方案逻辑的一部分,你最终放弃了例外,但一般没有得到批准。 否则,你就能够归还一个违约的物体,或者通过某种其他手段表示失败,但其中任何一个都不会达到特别的目的。

// You could pass in output streams for prompts and errors, too.
template<typename T>
T read(std::istream& is, std::string const& prompt, std::string const& error) {
    T t;
    while ((std::cout << prompt) && !(is >> t)) {
        if (is.eof())
            throw std::runtime_error("End of stream.");
        std::cerr << error;
        is.clear();
        is.ignore(std::numeric_limits<std::streamsize>::max(),  
 );
    }
    return t;
}

int main() {
    std::vector<int> values;
    int i = 1;
    // This way, an input of 0 will terminate the loop.  I ve deviated from
    // `exit  terminating the loop -- sentinel values like that aren t very
    // flexible, so I wouldn t advise using it.
    try {
        while (i = read<int>(std::cin, "Please enter an integer: 
", "Error!
"))
            values.push_back(i);
    }
    catch (std::exception& e) {
        // Have fun figuring out if this is end of input or something utterly unrelated.
    }
}

This will let you take input several times, but it s not quite as neat, and takes a lot more code.

Finally, a balance of the two uses lexical_cast for the conversion. This is part of boost, but if you d rather only use things provided by the standard library, it can be implemented as

template<typename OUT, typename IN>
OUT lexical_cast(IN const& in) {
    std::stringstream ss;
    OUT o;
    ss << in;
    ss >> o;
    // You may want more thorough error checking code
    if (!ss)
        throw std::runtime_error("Bad cast");
    return o;
}

这将根据代表的文字而不是双手方式,从一个类别变为另一个类别。 你们现在能够这样做。

int main() {
    std::vector<int> values;
    std::string input;
    while ((std::cout << "Enter an integer: ") && (std::cin >> input)) {
        if (input == "exit")
            break;
        try {
            values.push_back(lexical_cast<int>(input));
        }
        catch (std::runtime_error& e) {
            // Tell about the error, etc.
        }
    }
 }

在某些情况下,其中一种显然比另一种情况好;这取决于预期的投入方法(将是一种用户打打字材料或改用标准投入的档案?)以及必须如何抵制不正确的投入。

I think in c++ your only option is to read a string.

You cold fall back to using C s scanf, which does return number of entries successfully read and will return 0, if you try to read integer, but characters have been entered.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签