我有一个包含[51,53]
的c_str。我想将这些对分成两个整数。它们位于c_str中,因为我从输入文件中读取它们。
必须有一种简单的方法来解析它们。我在考虑使用.at
函数:但我相信我已经成功了。此外,它不起作用,因为它输出:
pair: 0x7ffffcfc2998
pair: 0x7ffffcfc2998
etc
string pairstring = buffertm.c_str();
stringstream pair1, pair2;
int pairint1, pairint2;
pair1 << pairstring.at(1) << pairstring.at(2);
cout << "pair: " << pair1;
pair1 >> pairint1;
pair2 << pairstring.at(4) << pairstring.at(5);
//cout << "pair: " << pair2;
pair2 >> pairint2;
有更好的方法吗?
答案 0 :(得分:5)
这样的事情:
char c1, c2, c3;
int first, second;
std::istringstream iss(str);
if (iss >> c1 >> first >> c2 >> second >> c3
&& c1 == '[' && c2 == ',' && c3 == ']' )
{
// success
}
您可能需要额外检查以查看结束括号后是否还有其他字符:
if ((iss >> std::ws).peek() != EOF) {
//^^^^^^^^^^^^^^
// eats whitespace chars and returns reference to iss
/* there are redundant charactes */
}
答案 1 :(得分:4)
使用C ++ 11 std::stoi
:
char c_str[] = "[51,53]";
std::string s(c_str);
int num1 = std::stoi(s.substr(1, 2));
int num2 = std::stoi(s.substr(4, 2));
如果您知道数字将超出10-99
范围,请改用:
char c_str[] = "[5156789,5]";
std::string s(c_str);
s.assign(s.substr(1, s.size() - 2)); // Trim away '[' and ']'
std::string::size_type middle = s.find(','); // Find position of ','
int num1 = std::stoi(s.substr(0, middle));
int num2 = std::stoi(s.substr(middle + 1, s.size() - (middle + 1)));
如果无法解析数字,函数stoi
将抛出std::invalid_argument
。
修改强>
对于只能解析 base-10 数字的更多rubust解决方案,您应该使用以下内容:
char c_str[] = "[51,0324]";
int num1, num2;
try {
std::string s(c_str);
s.assign(s.substr(1, s.size() - 2));
std::string::size_type middle = s.find(',');
std::unique_ptr<std::size_t> pos{new std::size_t};
std::string numText1 = s.substr(0, middle);
num1 = std::stoi(numText1, pos.get()); // Try parsing first number.
if (*pos < numText1.size()) {
throw std::invalid_argument{{numText1.at(*pos)}};
}
std::string numText2 = s.substr(middle + 1, s.size() - (middle + 1));
num2 = std::stoi(numText2, pos.get()); // Try parsing second number.
if (*pos < numText2.size()) {
throw std::invalid_argument{{numText2.at(*pos)}};
}
} catch (const std::invalid_argument& e) {
std::cerr << "Could not parse number" << std::endl;
std::exit(EXIT_FAILURE);
}
尝试将字符串解析为std::invalid_argument
时会抛出"1337h4x0r"
,这与使用std::istringstream
时不同。 Se this for more info
答案 2 :(得分:3)
出于多种原因,我建议采用两步法,而不是一次性尝试。
此外,其中一些很大程度上取决于你可以安全地做出什么样的假设。
1)只是标记化。如果你知道它将以“[”开头并且你知道会有一个逗号,并且你知道你只会得到两个数字,在字符串中搜索“[,”然后使用substr()来获取所有内容它和逗号之间。这是一个令牌。然后从逗号到“]”执行类似的操作以获取第二个标记。
2)一旦你有两个字符串,将它们转换为整数是相对简单的,并且有很多方法可以做到。
在我打字的时候添加了一些答案,但我仍然建议采用两步法。
答案 3 :(得分:1)
如果您对字符串的格式有合理的信心,可以将整个事物放入stringstream
,然后使用提取运算符; e.g:
stringstream strm(pairstring);
int pairint1 = 0, pairint2 = 0;
char c = 0;
strm >> c >> pairint1 >> c >> pairint2 >> c;
实际上你也想在那里进行一些错误检查,但希望这足以让你开始。
答案 4 :(得分:0)
答案 5 :(得分:0)
我有一个包含[51,53]
的c_str
不,c_str()
不是数据结构,它是std::basic_string
的一种方法,它返回一个常量C字符串,其数据等同于std::string
中存储的数据。
string pairstring = buffertm.c_str();
很麻烦,只需string pairstring = buffertm;
或直接使用buffertm
。
其次,你以错误的方式使用你的字符串流,你应该使用istringstream
(这里你将它用作ostringstream
:
int i, j;
istringstream iss(buffertm);
iss.get()
iss >> i;
iss.get()
iss >> j;
iss.get().