我觉得这是一个相当基本的问题,但我在互联网上搜索了一个多小时,我还没有找到答案。
我正在编写一个文本接口,它将输入作为字符串。如果输入字符串是数字,我想将字符串转换为整数并将其推送到我创建的堆栈。
文本界面的代码如下:
#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配置不正确,有没有人对如何使其正确有任何建议,或建议资源阅读?
答案 0 :(得分:2)
不要检查它是否看起来像一个整数然后将其转换为整数。相反,将其转换为整数,看看是否有效。使用std::stoi
(或stol
或stoll
,具体取决于您对该数字的预期程度。)(在<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'; }
,因为这是废话,显然还不够。负面数字,浮点数以及我之前提到的所有内容如何?