在std::string::find_first_not_of
的{{3}}上,它提供了文本宏替换的示例:
#include <string>
#include <iostream>
int main() {
std::string to_search = "Some data with %MACROS to substitute";
std::cout << "Before: " << to_search << '\n';
auto pos = std::string::npos;
while ((pos = to_search.find('%')) != std::string::npos) {
// Permit uppercase letters, lowercase letters and numbers in macro names
const auto after = to_search.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", pos + 1);
// Now to_search[pos] == '%' and to_search[after] == ' ' (after the 'S')
if(after != std::string::npos)
to_search.replace(pos, after - pos, "some very nice macros");
}
std::cout << "After: " << to_search << '\n';
}
这很有效,除非%MACROS
位于字符串的末尾(如下所示),在这种情况下find_first_not_of
返回std::string::npos
,这将变成无限循环。
std::string to_search = "Some data with %MACROS";
为什么这个特定的代码块完全跳过替换%MACROS,因为它位于字符串的末尾?不考虑\ 0作为&#34;不是&#34;它给出的字符集是什么?
答案 0 :(得分:2)
find_first_not_of()
在找不到匹配项时会返回npos
。在您的情况下,当宏位于字符串的末尾时,没有匹配的字符,因此npos
。要处理这种情况,只需在执行替换之前将npos
替换为size()
。
试试这个:
#include <string>
#include <iostream>
int main() {
std::string to_search = "Some data with %MACROS to substitute";
std::string replace_with = "some very nice macros";
std::string macro_name;
std::cout << "Before: " << to_search << '\n';
std::string::size_type pos = 0;
while ((pos = to_search.find('%', pos)) != std::string::npos)
{
// Permit uppercase letters, lowercase letters and numbers in macro names
auto after = to_search.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", pos + 1);
// if no matching chars, set after past the last char...
if (after == std::string::npos)
after = to_search.size();
auto count = after - pos;
if (count > 1)
{
// extract the macro name and replace the macor only if
// the name actually maps to something worth replacing...
macro_name = to_search.substr(pos + 1, count - 1);
if (macro_name == "MACROS")
{
// found a macro!
to_search.replace(pos, count, replace_with);
// start the next search after the replaced text...
pos += replace_with.size();
continue;
}
// check for other macros as needed...
}
// no matching macro, skip the '%' and search again from the next char...
++pos;
}
std::cout << "After: " << to_search << '\n';
}