![](/img/trans.png)
[英]How can I convert const char* to string and then back to char*?
[英]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.