将非null终止c字符串转换为终止c字符串的最简洁方法

时间:2016-03-28 17:43:57

标签: c++ templates c-strings c++03 null-terminated

我有一些返回非空终止字符串的遗留函数。

struct legacy {
    char a[4];  //not null terminated
    char b[20]; //not null terminated 
};

我传递了很多这些char数组,我需要一种干净的方法将它们转换为null终止。

截至目前,这就是我在做的事情:

legacy foo;
std::string a(foo.a, sizeof(foo.a));
std::string b(foo.b, sizeof(foo.b));
bar(foo.a.c_str(), foo.b.c_str());

是否有更简洁的方法可以使用类和模板将此代码缩减为类似......

legacy foo;
bar(make_null_terminated(foo.a), make_null_terminated(foo.b));

3 个答案:

答案 0 :(得分:8)

这样的事情应该做:

struct make_null_terminated {
    template <size_t sz>
    make_null_terminated(char (&lit)[sz]) : str(lit, sz) {}
    operator const char* () const { return str.c_str(); }
private:
    std::string str;
}

这将允许您按照自己的方式使用它。

编辑标签编辑完成后,我摆脱了std::beginstd::endl

答案 1 :(得分:0)

你可以简单地说:

std::string a(std::begin(foo.a), std::end(foo.a));

答案 2 :(得分:0)

我能想到的最简洁的方法是使用std :: string的迭代器构造函数,指针是一种迭代器。

bar(std::string(std::begin(foo.a), std::end(foo.a)).c_str(),
    std::string(std::begin(foo.b), std::end(foo.b)).c_str()); 

这里发生了什么?

  1. 通过复制foo.a中的字节并添加尾随零来构造一个字符串(这封装在std :: string中)

  2. ditto for foo.b

  3. 在临时字符串上调用方法c_str()以获取指向内部以null结尾的c字符串的指针。

  4. 致电栏

  5. 销毁临时字符串