【问题标题】:How to convert from a string array to a char array array?如何从字符串数组转换为字符数组数组?
【发布时间】:2019-05-22 21:15:34
【问题描述】:

我想将一组参数传递给 exec() 函数。当前参数都是字符串。如何将字符串数组转换为 char 数组?

现在我正在使用 const_cast 来删除 const。代码看起来不太好。 有没有更好的解决方案?

示例代码如下:

void f(const string &dev, const string &status){

  char* args[] = {"link", "set", "dev", const_cast<char*>(dev.c_str()), 
  const_cast<char*>(status.c_str())};
  execv("/sbin/ip", args);
}

【问题讨论】:

  • 为什么不在 iso 类型中添加 const 呢?
  • char* arg0 = "link" 也应该是有问题的,因为const(或此处的演员)也丢失了......
  • 我不确定,但devstatus 的生命周期在这里重要吗?您正在调用execv 并使用std::string 返回的字符串填充它,这些字符串在main 退出后超出范围。
  • 你可以按值取参数,而不是 const ref 吗? (一种删除const 的方法,如果在函数中完成了复制(如答案中所建议的,它可能会避免额外的副本)。

标签: c++ linux exec


【解决方案1】:

最好将args 声明为char const* 的数组:

char const* args[] = {"link", "set", "dev", dev.c_str(), status.c_str()};

但是,如果您确实需要 char* 而不是 char const*,正如 execv 所要求的,我们需要 std::string::data

void f(const string &dev_, const string &status_){
  // Note: string literals don't convert to char* in C++,
  // although some compilers allow it as an extension.

  // Declare these as arrays so we can form `char*`s to them:
  char link[] = "link";
  char set[] = "set";
  char dev_lit[] = "dev";

  // No choice but to copy the const args:
  std::string dev{dev_};
  std::string status{status_};

  // C++17-specific:
  char* args[] = {link, set, dev_lit, dev.data(), status.data()};
  execv("/sbin/ip", args);
}

在 C++17 之前,可以使用&amp;status[0] 而不是status.data(),即使status.size() == 0 也是正确的。

【讨论】:

  • 这种方法的问题是execv 正在使用char *const。如果我传递char const*,它将抛出错误invalid conversion from ‘const char**’ to ‘char* const*’
  • @stcheng 是的,这就是为什么我还提供了如何获取char*s 而不是char const*s。
  • 刚刚更新了我的问题,这两个字符串也是 const :(
  • 当你复制参数时,逐个复制可能是有意义的。
【解决方案2】:

代码看起来不太好。有没有更好的解决方案?

为了它的价值,使用

char* args[] = {"link", "set", "dev", ... };

一开始就错了。字符串文字可以衰减到char const*,而不是char*

我建议使用一个使用 strdup 的辅助函数来为您提供输入字符串的副本。

char* toArg(std::string const& s)
{
    return strdup(s.c_str());
}

并使用

char* args[] = {toArg("link"), toArg("set"), toArg("dev"), toArg(dev), toArg(status)};

【讨论】:

  • 顺便说一句,"link" 仍然不是char*
  • @Jarod42,真的。
  • 这是 C++,不是 C。不要使用 strdup,使用 std::string 副本。此外,为字符串字面量分配堆内存很浪费。
猜你喜欢
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多