繁体   English   中英

如何将const char *转换为char [256]

[英]How can I convert const char* to char[256]

如何将const char*转换为char[256]

const char *s = std::string("x").c_str();
char c[256] = /* ??? */

您不能使用字符指针初始化数组。 但是您可以复制字符串。 例如:

const char *s = get_the_string();
char c[256]{};
auto n = std::strlen(s);
if (std::size(c) <= n)
    throw std::runtime_error(
        "The buffer is too small. Contact your local C++ maintainer");
std::memcpy(c, s, n);

使用恒定大小的数组的明显问题是,您需要考虑如何处理输入字符串不合适的情况。 在这里,我使用了一个异常,但是如果您不愿意这样做,则可以使用自己选择的错误处理。


您不能从const char *s = std::string("x").c_str();复制const char *s = std::string("x").c_str(); 但是,由于指针是悬空的,因此尝试访问指向的数据将具有不确定的行为。

将内容从const类型复制到可编辑的内容实际上是删除const的唯一方法。 我猜你会得到一个const,因为有些东西将其标记为“您不能更改”,即只读。

纯*的麻烦在于您需要知道它有多长时间。 对于以null终止的字符串,strlen可以为您提供该大小(因此可以与strncpy一起使用)。

strncpy(c,s,256);

如果const char *只是字节,则需要另一种方法。

const char*复制到char[]方法有很多:

#include <cstring>
const char *s = "x";
char c[256]{};
std::strncpy(c, s, 255);
#include <algorithm>
#include <cstring>
const char *s = "x";
char c[256]{};
std::copy_n(s, std::min(std::strlen(s), 255), c);
#include <string>
const char *s = "x";
char c[256]{};
std::string(s).copy(c, 255);
#include <sstream>
const char *s = "x";
char c[256]{};
std::istringstream iss(s);
iss.read(c, 255);
//or: iss.get(c, 256, '\0');

strncpy(c,s,256); 它对我有用

正如其他人指出的

const char *s = std::string("x").c_str();

是错误的代码。 它有效地创建了一个新字符串,在其中放入“ x”,返回一个指向“ x”的指针,释放了该字符串。 所以,现在什么s指向未定义

如果您不在该行中创建字符串,那将是安全的。 例如

const auto t = std::string("x");
const char *s = t.c_str();

现在t将是有效的,直到当前范围退出为止, t也将是有效s

至于复制到256个字符的数组,可以说最优的解决方案是

char c[256];
std::strncpy(c, s, 255);
c[255] = '\0';

为什么?

这条线

char c[256];

在堆栈上分配256个字节的空间,并且不执行其他任何操作。

这条线

std::strncpy(c, s, 255);
  • 如果s少于255个字符,则将这些字符复制到c然后写零以将缓冲区填充到第254个元素
  • 如果s为255个字符或更多,则仅复制前255个字符

这行在结尾处放置一个以零结尾的零

c[255] = '\0';

让我们与其他解决方案进行比较

这个

    char c[256];
    std::strncpy(c, s, 256);

这个答案的问题是,如果s超过255个字符,则c的末尾将不会以0结尾。 到底重要与否取决于您,但十分重要的是999次。

这个

    char c[256]{};
    std::strncpy(c, s, 255);

安全但较慢。 区别在于{}位于char c[256]{}的末尾。 如果没有该{} ,则仅分配c数组。 不仅为它分配了c而且对所有256个字符均初始化为0。 这意味着对于从s复制到c每个字符,都进行了费力的工作,将字符开头清零。 这可能是工作的两倍

const char *s = get_the_string();
char c[256]{};
auto n = std::strlen(s);
if (std::size(c) <= n)
    throw std::runtime_error(
        "The buffer is too small. Contact your local C++ maintainer");
std::memcpy(c, s, n);

与上面相同,做了两倍的工作,尽管指出必须选择如何处理太大而无法容纳c s很好。

所有使用char c[256]{}代替char c[256]的示例都可能使工作加倍。 做两倍的工作不一定很糟糕,但是鉴于最佳版本很简单,因此没有理由不使用它。

另一个问题是使用幻数。 不幸的是,C ++直到C ++ 17(std :: size)才添加数组大小函数,因此我们只能自己做一个

template<class T, size_t N>
constexpr size_t array_size(T (&)[N]) { return N; }

所以我们可以做到这一点

char c[256];
std::strncpy(c, s, array_size(c) - 1);
c[array_size(c) - 1] = '\0';

因此,现在如果我们更改c的大小,代码仍然可以正常工作。

用于获取数组中元素数量的标准版本是C ++ 17中添加的std::size ,但是C ++ 17显然仍然很少见,我尝试过的在线C ++编译器(在Google上获得了一些成功)都不支持它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM