如何在 C++ std::system() 中插入多个变量?

How to insert multiple variables inside c++ std::system()?

我正在尝试在 std::system 函数中添加多个变量。通过在最后使用 .c_str 它只接受一个变量。

system(("riverctl map normal " + modkey + " " + i + " set-focused-tags " + decimal).c_str);

如果系统块中声明的所有变量都是原始变量(我猜 'modkey' 已经是 std::string)——你需要将所有内容都转换为 std::string 并调用 c_str作为函数。

system(("riverctl map normal " + modkey + " " + std::to_string(i) + " set-focused-tags " + std::to_string(decimal)).c_str());

这个代码

"riverctl map normal " + modkey

在两件事上调用 operator+"riverctl map normal "modkeyoperator+是哪个取决于+.

的两个操作数的类型

您希望它调用 operator+ 来连接字符串;如果前两个操作数中的任何一个是字符串 (std::string),则第一个 + 会做正确的事情,而接下来的所有 + 也会做同样的事情(因为第一个的结果+ 将是 std::string).

如果 modkey 是一个整数(任何类型的整数,包括 char),这个 + 会做错事(不需要的指针运算)。要解决此问题,请将前两个操作数中的任何一个转换为字符串。如果 modkey 是整数,则无论如何都必须使用 std::to_string ,因此不需要转换第一个操作数。但为了保持一致性(即不再担心如果更改消息格式会发生什么),您可能甚至想转换第一个:

// minimal required change
system(("riverctl map normal " +
        std::to_string(modkey) + " " +
        std::to_string(i) + " set-focused-tags " + 
        std::to_string(decimal)).c_str());

// more robust code (C++14 and later)
system(("riverctl map normal "s +
        std::to_string(modkey) + " " +
        std::to_string(i) + " set-focused-tags " + 
        std::to_string(decimal)).c_str());

// more robust code (C++11)
system((std::string("riverctl map normal ") +
        std::to_string(modkey) + " " +
        std::to_string(i) + " set-focused-tags " + 
        std::to_string(decimal)).c_str());

如果你的命令行太复杂,你可能想使用临时流来格式化;那么惊喜就少了:

std::ostringstream stream;
stream << "riverctl map normal " << modkey << " " << i << " set-focused-tags " << decimal;
system(stream.str().c_str());

我推荐格式库:

C++20 format standard library

#include <cstdlib>
#include <format>

auto test(int modkey, int i, int decimal)
{
    auto cmd = std::format("riverctl map normal {} {}  set-focused-tags {}",
                           modkey, i, decimal);
    system(cmd.c_str());
}

{fmt} library

#include <cstdlib>
#include <fmt/core.h>

auto test(int modkey, int i, int decimal)
{
    auto cmd = fmt::format("riverctl map normal {} {}  set-focused-tags {}",
                           modkey, i, decimal);
    system(cmd.c_str());
}