[C] 每天來點字串用法 (3) - from const char* to char*

這次沒有拖到欸d(`・∀・)b
今天帶來的不是函式,而是一個小技巧:
  • const char* 轉成 char*
  有時候可能在將字串傳入函式時,會出現以下錯誤:
error: invalid conversion from 'const char*' to 'char*'
note: expected 'char *' but argument is of type 'const char *'
  這是因為 const char* 沒辦法自動轉換成 char*,那麼基本上是沒救了啦,不過有一些方法可以繞過編譯器檢查或達到與轉換型別相同的效果:
          1) 直接修改函式參數的型態定義,但原本函式庫裡的宣告根本不能改。
          2) 用 const_cast<char*>(cptr),這個雖然可以強制轉換,但若透過轉換後的指標更改常數的值,將會是 undefined behavior。
          3) 使用上一篇提到的 strcpy(),但小心緩衝區覆蓋,或是使用到不知道指到什麼的指標。

  下面這裡提供 2) 和 3) 的使用範例:
#include <iostream>
#include <cstring>
#include <string>

using namespace std;

int main(){
    string str("hello world");
    cout << "(before) str: " << str << endl;
    char s[16];
    char *ptr1, *ptr2 = s;
    // ptr1 = str.c_str();   error: c_str() 回傳 const char*
    ptr1 = const_cast<char*>(str.c_str());
    ptr1[2] = 'r';  // undefined behavior
    cout << "ptr1: " << ptr1 << endl;
    strcpy(ptr2, str.c_str());
    ptr2[3] = 't';
    cout << "ptr2: " << ptr2 << endl;
    cout << "(after) str: " << str << endl;

    return 0;
}
  參考輸出:
(before) str: hello world
ptr1: herlo world
ptr2: herto world
(after) str: herlo world
  這裡我們使用 string.c_str() 方法來取得 const char*,並依照上面所說的 2) 和 3) 來進行型別間的轉換。但這裡並不保證在每個編譯器之下都會有相同的輸出,因為在行 14 的地方出現了 undefined behavior。(我使用的編譯器:Code::Blocks 16.01 版所附的 mingw32-g++)

參考資料:
  1) cppreference - const_cast
  2) http://windsplife.blogspot.tw/2010/09/cstaticcast-dynamiccast-reinterpretcast.html 的 const_cast 部分
  3) 我的腦袋

留言

這個網誌中的熱門文章

[C] 每天來點字串用法 (2) - strcpy()、strncpy()

[Python] *args 和 **kwargs 是什麼?一次搞懂它們!

[C] 每天來點字串用法 (5) - strcat()、strncat()