多行替换成一行

时间:2018-09-13 09:58:51

标签: c++ string c++11

我有一个sql语句,为了进行调试,我想打印它。该语句包含占位符,我想在打印前在一条指令行中填充占位符。这是有效的还是UB?

std::string query("SELECT A, B FROM C WHERE D = ? and E = ?;");
std::cout << query.replace(query.find("?"), 1, "123").replace(query.find("?"), 1, "234") << std::endl;

是指令的顺序

  1. 查找第一个问号的位置
  2. 替换查询中的第一个字符串
  3. 在第一次替换后查找第二个问号的位置
  4. 替换查询中的第二个字符串

保证或有可能在两个find之类的操作之前都可以调用两个replace之类的操作

  1. 查找第一个问号的位置
  2. 在第一次替换之前找到第二个问号的位置
  3. 替换查询中的第一个字符串
  4. 替换查询中的第二个字符串

我问是因为:

  

几乎所有C ++运算符的操作数求值顺序   (包括对函数参数的求值顺序   函数调用表达式和求值顺序   未指定任何表达式中的子表达式)。编译器可以   以任何顺序评估操作数,并且当   再次计算相同的表达式。

编辑: 在该项目中不能使用第三方依赖项。

3 个答案:

答案 0 :(得分:3)

max(p) * max(qs[j])

query.replace(query.find("?"), 1, "123").replace(query.find("?"), 1, "234")彼此未排序。 因此结果在可能的序列之间是不可预测的。

答案 1 :(得分:1)

在求值规则中找不到任何严格指定链接函数的函数参数顺序的内容。也就是说,对于您而言,您可以知道:

  1. 第一个replace在第二个之前排序,因为第二个以其返回值进行操作

  2. 每个find调用在使用其返回值作为参数的replace之前进行排序

但是您想要的是第一个replace在第二个find之前排序,因此没有这样的保证。作为参考,请参阅规则here

答案 2 :(得分:1)

您可以多次使用boost::algorithm::replace_first

#include <boost/algorithm/string/replace.hpp>
#include <iostream>
#include <string>

int main() {
    std::string query("SELECT A, B FROM C WHERE D = ? and E = ?;");
    for(auto replacement : {"123", "1"})
        boost::algorithm::replace_first(query, "?", replacement);
    std::cout << query << '\n';
}

请注意,这种简单的字符串替换不适用于需要引用的替换字符串。