检查输入字符串是否为数字并且在C ++中,如果是,则将其转换为int(正则表达式?)

时间:2013-09-26 22:38:39

标签: c++ regex match

我觉得这是一个相当基本的问题,但我在互联网上搜索了一个多小时,我还没有找到答案。

我正在编写一个文本接口,它将输入作为字符串。如果输入字符串是数字,我想将字符串转换为整数并将其推送到我创建的堆栈。

文本界面的代码如下:

#include <iostream>
#include "textInterface.h"
#include "Stack.h"
#include <string>
#include <regex>

using namespace std;

void Interface(){
    Stack stack = Stack();

    string input;

    cout << "Please enter a number or operation";
    cin >> input;


     if (input == "."){
         cout << stack.pop();
     } //this pops the stack

     if (input == "+"){
         int a = stack.pop();
         int b = stack.pop();
         int c = a + b;
         stack.push(c);
     } //pops the first two things off the stack, adds them, and pushes the result

     if (input == "-"){
        int a = stack.pop();
        int b = stack.pop();
        int c = a - b;
        stack.push(c);
     } //pops the first two things off the stack, subtracts them, and pushes the result

     if (input == "*"){
        int a = stack.pop();
        int b = stack.pop();
        int c = a * b;
        stack.push(c);
     } //pops the first two things off the stack, multiplies them, and pushes the result

     if (input == ".s"){
         cout << stack.count();
     } //returns the size of the stack

     if (regex_match(input, "[0-9]")){
         int num;
         stringstream convert(input);
         convert >> num;
         stack.push(num);
     } //This is the part with the error!!! 

}

就像我说的,我想检查输入是否是数字,如果是,将字符串转换为int并将其推入堆栈。我之前使用过正则表达式,但它已经有一段时间了,而且它是在Python中(我是C ++的新手)。我知道我的regex_match配置不正确,有没有人对如何使其正确有任何建议,或建议资源阅读?

2 个答案:

答案 0 :(得分:2)

不要检查它是否看起来像一个整数然后将其转换为整数。相反,将其转换为整数,看看是否有效。使用std::stoi(或stolstoll,具体取决于您对该数字的预期程度。)(在<string>中):请参阅here

如果字符串无法转换为指定大小的整数,则会抛出异常,因此您必须在try内执行该函数。 (如果你是一个pythonista,那种风格应该很熟悉。)

另外,如果有一个数字但它没有占用整个字符串(即尾随垃圾),则size_t指向的第二个参数将被设置为第一个未使用字符的索引,所以如果要检查整个字符串是否为数字,还应检查以确保返回的索引是输入字符串的大小。

如果您对异常感到不舒服,即使是标准库抛出的异常,也可以使用基础标准c函数strtol和朋友。那些具有类似的接口,但使用任意值返回结合设置errno来尝试通信失败。我个人认为异常界面不那么繁琐,但是,一如既往,品味各不相同。

答案 1 :(得分:0)

我赞成你的问题,因为我遇到了同样的问题,但没有找到明显的解决方案。 我开发了一个有点缺陷的解决方案,但对于普通情况来说已经足够了。从谷歌来看,它肯定是缺乏答案的东西。所以为了人类的知识,我将在这里发布我的解决方案。

bool StringCtr::IsNumeric(bool onlyIntegersYieldTrue /*= false*/, int intRadix /*= 0*/) const
{
    _ASSERT(intRadix == 0 || intRadix >= 2 && intRadix <= 36);

    bool const acceptsFloats = !onlyIntegersYieldTrue;
    bool ok = false;
    if (!Empty())
    {
        char* pEnd = 0;
        long li1;
        li1 = strtol(Cstr(), &pEnd, intRadix);
        ok = ! (li1 == 0L && pEnd == Cstr());
        if (!ok && acceptsFloats)
        {
            double d1;
            d1 = strtod(Cstr(), &pEnd);
            ok = ! (d1 == 0.0 && pEnd == Cstr());
        }
        if (ok && !acceptsFloats)
        {
            ok = ok && !Contains(".");
            ok = ok && !Contains("e");
        }
    }           
    return ok;
}

所以这是我的字符串类的一个方法,从那里调用的其他方法都有自我解释,我相信。这是尝试使用能够接受许多格式的标准C tokenizer(strtol)。这实际上是值得注意的事情,因为例如当使用0(自动)基数时,从0开始的数字将被解释为八进制基数。另外,它很方便,因为它会识别0x .. hexa表示法模式,并区分整数和浮点数。它甚至应该理解指数表示法,例如“-1.05e12”。

无论如何,这取决于你真正需要的解析能力,你认为你的用户会想到程序识别的那种符号约定?最后,不要听人说“这很简单,只需检查foreach (char c) { ok = c >= '0' && c <= '9'; },因为这是废话,显然还不够。负面数字,浮点数以及我之前提到的所有内容如何?

欢呼!