簡體   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