【发布时间】:2008-12-06 21:59:53
【问题描述】:
我正在尝试用 C++ 解析一个简单的字符串。我知道该字符串包含一些带有冒号的文本,后跟一个空格,然后是一个数字。我想只提取字符串的数字部分。我不能只对空格进行标记(使用 sstream 和
一些示例字符串可能是:
总磁盘空间:9852465
可用磁盘空间:6243863
部门:4095
我想使用标准库,但如果您有其他解决方案,您也可以发布,因为其他有相同问题的人可能希望看到不同的解决方案。
【问题讨论】:
我正在尝试用 C++ 解析一个简单的字符串。我知道该字符串包含一些带有冒号的文本,后跟一个空格,然后是一个数字。我想只提取字符串的数字部分。我不能只对空格进行标记(使用 sstream 和
一些示例字符串可能是:
总磁盘空间:9852465
可用磁盘空间:6243863
部门:4095
我想使用标准库,但如果您有其他解决方案,您也可以发布,因为其他有相同问题的人可能希望看到不同的解决方案。
【问题讨论】:
std::string strInput = "Total disk space: 9852465";
std::string strNumber = "0";
size_t iIndex = strInput.rfind(": ");
if(iIndex != std::string::npos && strInput.length() >= 2)
{
strNumber = strInput.substr(iIndex + 2, strInput.length() - iIndex - 2)
}
【讨论】:
!= -1!请改用!= string::npos。
find 返回npos,它定义了npos = -1。但是,npos 的类型为 std::size_t。一些编译器会在比较无符号数和有符号数时发出警告,并根据设置将其视为错误
为了完整起见,这里有一个简单的 C 解决方案:
int value;
if(sscanf(mystring.c_str(), "%*[^:]:%d", &value) == 1)
// parsing succeeded
else
// parsing failed
解释:%*[^:] 表示要读入尽可能多的非冒号字符,* 禁止赋值。然后,在冒号和任何中间空格之后读入整数。
【讨论】:
我不能只对空格进行标记(使用 sstream 和
没错,但你可以使用std::getline:
string not_number;
int number;
if (not (getline(cin, not_number, ':') and cin >> number)) {
cerr << "No number found." << endl;
}
【讨论】:
类似于 Konrads 的答案,但使用 istream::ignore:
int number;
std::streamsize max = std::numeric_limits<std::streamsize>::max();
if (!(std::cin.ignore(max, ':') >> number)) {
std::cerr << "No number found." << std::endl;
} else {
std::cout << "Number found: " << number << std::endl;
}
【讨论】:
ignore 和max 的一些问题(可能是由于有符号/无符号不匹配)。但是,此信息可能已过时。
我很惊讶没有人提到正则表达式。它们是作为 TR1 的一部分添加的,也包含在 Boost 中。这是使用正则表达式的解决方案
typedef std::tr1::match_results<std::string::const_iterator> Results;
std::tr1::regex re(":[[:space:]]+([[:digit:]]+)", std::tr1::regex::extended);
std::string str("Sectors: 4095");
Results res;
if (std::tr1::regex_search(str, res, re)) {
std::cout << "Number found: " << res[1] << std::endl;
} else {
std::cerr << "No number found." << std::endl;
}
这看起来需要做更多的工作,但恕我直言,你会从中得到更多。
【讨论】:
const std::string pattern(": ");
std::string s("Sectors: 4095");
size_t num_start = s.find(pattern) + pattern.size();
【讨论】: