[英]How to convert a `const char *` to simply `char *`?
我正在使用pdCurses庫,我的目標是只在我的C ++控制台游戲中使用字符串,但是curses mvinstr()
函數或任何insert函數都需要非const char *
作為參數。
string.c_str()
,但是返回一個const char *
,它顯然不適用於該函數。 (char *)string.c_str()
但這只會導致一個未處理的異常。 char *test = string.c_str()
但這也與const
不兼容。 我該怎么做才能解決這個問題?
我只是嘗試了const_cast(),我仍然得到一個異常拋出和中斷....我不知道為什么PDcurses只采用非const char指針.... =(
好吧,當我使用這段代碼時,使用char *緩沖區不起作用(time_s是sting):
size_t length;
char buffer[12];
length=time_s.copy(buffer,5,0);
buffer[length]='\0';
mvinstr(time_loc_y, time_loc_x, buffer);
我甚至在mvinstr()之前停了一下,並檢查了緩沖區的內容是“00/0”我想要的是什么。
但我得到一個訪問違規點“xutility”....
mvinstr(x,y,str)
和其他“從窗口中的當前或指定位置獲取字符(或寬字符),並將它們作為str
(或wstr
)中的字符串返回。”
該函數實際上將修改字符串,因此您無法安全地轉換const
,尤其是因為c_str
指定您不應修改返回的字符串。
你需要的東西是:
const MAX = 100;
char buf[MAX];
mvinnstr(x, y, buf, MAX);
...error checking...
string s = buf;
請注意,我避免mvinstr
支持mvinnstr
以避免緩沖區溢出的可能性。
怎么樣
char* buffer = &str[0];
int fetched_len = mvinnstr(time_loc_y, time_loc_x, buffer, str.size());
str.resize(fetched_len);
但是,一般情況下,您應該創建一個可寫緩沖區,而不是從包含它的指針中刪除const
。 例如
vector<char> charvec(MAX_LENGTH);
str = string(&charvec[0], mvinnstr(time_loc_y, time_loc_x, &charvec[0], charvec.size());
謹慎 - 如果使用was- const
數據的代碼試圖修改它,任何事情都可能發生。
簡而言之:
const std::string str = "...";
char *caution = const_cast<char *>(str.c_str());
但是,鑒於您正在處理未處理的異常,您可能需要在調用mvinstr()
之前mvinstr()
常量字符串的可修改副本。 也許:
const std::string str = "...";
char *caution = new char[str.length()+1];
str.copy(caution, str.length()+1);
...call to mvinstr()...
delete[] caution;
由於mvinstr
實際上是將數據存儲到char*
指向的數組中,因此不能在那里使用string
。 您需要分配一個char數組,將其傳遞給mvinstr
,然后根據需要將字符傳輸到string
。
如果您使用的函數可以使用const char *
聲明(即它實際上不會修改數組),那么您可以使用const_cast<>
來刪除const
。
const_cast<char *>(str.c_str());
但那不是你在這里做的。 如果你嘗試過const_cast
可能會有效,但這可能是偶然的,不是因為它應該工作,而且新的編譯器或庫版本可能隨時打破它。
嘗試類似下面的內容,然后在需要char*
地方使用buffer
。 正如Ben所提到的,你需要非常小心地保持緩沖區大於字符串加上null終止符。
const int BUFFER_SIZE = 255;
string str ("Your string");
char buffer[BUFFER_SIZE];
if (str.length() < BUFFER_SIZE)
{
size_t copy_length;
copy_length=str.copy(buffer,str.length(),0);
buffer[copy_length]='\0';
}
刪除const可以使用const_cast
完成,有時需要使用用C編寫的舊版接口並且不使用const。 在這種情況下,你可以這樣做:
char* ptr = const_cast<char*> (str.c_str());
但是,從c_str ()上的cplusplus參考頁面:
返回的數組指向一個內部位置,該位置具有此字符序列所需的存儲空間及其終止的空字符,但此數組中的值不應在程序中修改,只有在下次調用時才會保持不變。字符串對象的非常量成員函數。
這意味着您有責任確保不使用ptr
來修改字符串,並且必須適當地處理ptr
的生命周期。 即,在str
超出范圍之后,或者在str
上調用任何非const方法之后,您無法繼續使用ptr
。 如果你這樣做,你會進入未定義的行為,並可能會崩潰。
如果您正在尋找一種安全的方式來與使用char*
的舊接口進行交互,您可以創建自己的可寫副本:
char* ptr = new char[ str.size() + 1 ];
strcpy(ptr, str.c_str());
ptr[str.size()] = '\0';
// ... use ptr as much as you want...
delete [] ptr;
if (string.empty()) foo(const_cast<char*>(string.c_str());
一個更好但仍然邪惡的方法來刪除const是const_cast(const_string); (通過grep / search查找更好)
你遇到過巫婆異常嗎? 你剛讀過char *還是更改了值? 如果你改變了,你應該重新設計你的代碼。
const char* test = string.c_str();
不創建字符串的深層副本,只是指向string.data()的內部數據表示的指針。
=>(一個建議)找到一本C ++書籍,你可以從中深入了解c ++。 或類似於C ++。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.