我坚持设计这个功能:
//Turns "[0-9]+,[0-9]+" into two integers. Turns "[0-9]+" in two *equal* integers
static void parseRange(const std::string, int&, int&);
我无法访问正则表达式(这需要C ++ 11或Boost库)。我需要以某种方式找出字符串是否包含2个整数并将其拆分,然后得到每个整数。
我想我需要strstr
版本使用std::string
来查看是否有逗号和位置。我可能会以std::string::c_str
值运行。广泛的搜索引导我(但我想使用 std::string
,而不是C字符串):
void Generator::parseRange(const std::string str, int& min, int& max) {
const char* cstr = str.c_str();
const char* comma_pos;
//There's a comma
if((comma_pos=strstr(cstr, ","))!=NULL) { //(http://en.cppreference.com/w/cpp/string/byte/strstr)
//The distance between begining of string and the comma???
//Can I do this thing with pointers???
//Is 1 unit of pointer really 1 character???
unsigned int num_len = (comma_pos-cstr);
//Create new C string and copy the first part to it (http://stackoverflow.com/q/8164000/607407)
char* first_number=(char *)malloc((num_len+1)*sizeof(char));//+1 for \0 character
//Make sure it ends with \0
first_number[num_len] = 0;
//Copy the other string to it
memcpy(first_number, cstr, num_len*sizeof(char));
//Use atoi
min = atoi(first_number);
max = atoi(comma_pos+1);
//free memory - thanks @Christophe
free(first_number);
}
//Else just convert string to int. Easy as long as there's no messed up input
else {
min = atoi(cstr); //(http://www.cplusplus.com/reference/cstdlib/atoi/)
max = atoi(cstr);
}
}
我用Google搜索了很多。你不能说我没有尝试过。上面的函数有效,但我更喜欢一些不太天真的实现,因为你在上面看到的是旧时代的硬核C代码。这一切都依赖于事实,没有人会对输入感到困惑。
答案 0 :(得分:2)
您可以使用std::string
提供的内置搜索工具和std::atoi
来完成此操作,而无需复制或需要使用malloc
或new
来存储零件字符串。
#include <cstdlib>
#include <string>
void Generator::parseRange(const std::string &str, int& min, int& max)
{
// Get the first integer
min = std::atoi(&str[0]);
// Check if there's a command and proces the second integer if there is one
std::string::size_type comma_pos = str.find(',');
if (comma_pos != std::string::npos)
{
max = std::atoi(&str[comma_pos + 1]);
}
// No comma, min and max are the same
else
{
max = min;
}
}
或者正如其他人指出的那样,您可以使用std::istringstream
来处理整数解析。这将允许您在解析整数值时执行其他输入验证
#include <sstream>
#include <string>
bool Generator::parseRange(const std::string& str, int& min, int& max)
{
std::istringstream sst(str);
// Read in the first integer
if (!(sst >> min))
{
return false;
}
// Check for comma. Could also check and error out if additional invalid input is
// in the stream
if (sst.get() != ',')
{
max = min;
return true;
}
// Read in the second integer
if (!(sst >> max))
{
return false;
}
return true;
}
答案 1 :(得分:1)
这个更原生的版本是什么:
void Generator::parseRange(const std::string str, int& min, int& max) {
stringstream sst(str);
if (!(sst>>min && sst.get()==',' && sst>>max))
cerr<<"String has an invalid format\n";
}
答案 2 :(得分:1)
您可以使用std::string
功能轻松完成所有搜索和分离。
int pos = str.find(',');
assert(pos != std::string::npos);
std::string first = str.substr(0, pos);
std::string second = str.substr(pos+1, -1);
或者,您可以非常轻松地使用stringstream
进行解析。例如:
std::istringstream s(str);
int one, two;
char ch;
s >> one >> ch >> two;
assert(ch == ',');
请注意,这也可以很容易地将字符串分开并将各个部分转换为数字。
答案 3 :(得分:1)
不需要std :: whatever,它只会消耗更多的内存,而且不会有不易读的代码。
尝试使用大约1980年的C代码,应该可以做到这一点:
void generator::parse_range (const std::string input, int & min, int & max)
{
const char * scan = input.c_str();
min = (int) strtol (scan, &scan, 0);
max = (*scan == ',') ? (int)strtol (scan+1, &scan, 0) : min;
if (errno || *scan != '\0') panic ("you call that numbers?");
}
这将接受十六进制或八进制输入,但您可以使用第三个参数修复基数 您还可以在第一次转换后检查errno或测试长整数溢出,但我认为这不是您问题中最糟糕的部分:)