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

文章推薦指數: 80 %
投票人數:10人

由 const char* 轉成 char*. 有時候可能在將字串傳入函式時,會出現以下錯誤: error: invalid conversion from 'const char*' to 'char*' note: expected 'char ... 跳到主要內容 [C]每天來點字串用法(3)-fromconstchar*tochar* 取得連結 Facebook Twitter Pinterest 以電子郵件傳送 其他應用程式 2月14,2018 這次沒有拖到欸d(`・∀・)b 今天帶來的不是函式,而是一個小技巧: 由constchar*轉成char*  有時候可能在將字串傳入函式時,會出現以下錯誤: error:invalidconversionfrom'constchar*'to'char*' note:expected'char*'butargumentisoftype'constchar*'  這是因為constchar*沒辦法自動轉換成char*,那麼基本上是沒救了啦,不過有一些方法可以繞過編譯器檢查或達到與轉換型別相同的效果:      1) 直接修改函式參數的型態定義,但原本函式庫裡的宣告根本不能改。

      2)用const_cast(cptr),這個雖然可以強制轉換,但若透過轉換後的指標更改常數的值,將會是undefinedbehavior。

     3)使用上一篇提到的strcpy(),但小心緩衝區覆蓋,或是使用到不知道指到什麼的指標。

 下面這裡提供2)和3)的使用範例: #include #include #include usingnamespacestd; intmain(){ stringstr("helloworld"); cout<(str.c_str()); ptr1[2]='r';//undefinedbehavior cout< 函式宣告:char*strcpy(char*dest,constchar*src);char*strncpy(char*dest,constchar*src,size_tcount); 先說strcpy(),將來源字串(src)複製到目的地(dest),並回傳dest指向的字串,要注意的有以下兩點:     1)第一個參數是目的地(dest),第二個是來源(src)     2)會有緩衝區溢位(bufferoverflow) 的問題 來看看何謂緩衝區溢位:假設有一程式進行了如下宣告:inti=5;chars[8]="Hi1234"; 那麼這些變數的記憶體配置可能如下: 如果今天我們進行了如下操作:strcpy(s,"hellosky"); 那麼記憶體裡的內容就會變成如下: 於是這時i的值就會變成121,我們可以用以下程式來驗證:#include#includeintmain(void){inti=5;chars[8]="Hi1234";printf("addressofi:%p\naddressofs:%p\n",&i,s);//i:0028ff1c,s:0028ff14strcpy(s,"hellosky");printf("valueofs:%s\nvalueofi:%d\n",s,i);//s:hellosky,:121return0;} 為了解決這樣的問題,我們可以改用strncp 繼續閱讀 [Python]*args和**kwargs是什麼?一次搞懂它們! 4月30,2018 在翻閱Python的函式庫時常常會看到定義參數的地方放了*args和**kwargs這樣的東西,這究竟是什麼呢?讓我們先談談函式參數的定義。

預設參數 一般的定義方法就不多說了,直接來看有預設值的參數:defplus(a,b,c=None):res=a+b+(cifcelse0)returnres 預設參數的用處通常是實作函式重載用的,可以使一個函式在接受引數時更有彈性,而要注意的語法問題是:預設參數在函式定義時一定要放在非預設參數的後面。

 但如果我們想實作無限版的plus()函式呢?總不可能一直增加預設參數吧! 這時候我們可以用「*」來將引數收集到一個tuple中。

*-收集至Tuple 先來看看範例:defplus(*nums):res=0foriinnums:res+=ireturnres 透過*收集的引數會被放到一個tuple中,所以我們可以使用for來對它進行迭代。

 這樣就可以理解為什麼要使用*args這個參數了,但是**kwargs又是什麼呢?我們要先從關鍵字引數來說起:關鍵字引數KeywordArgument 在呼叫print()時,我們有時會指定sep參數做為分隔輸出的字元,或是使用end參數來更改最後的換行字元。

像這樣不用理會參數的真正順序,而只要給定名字然後指定值的情況,就是在使用關鍵字引數。

 如果我們要指定的參數太多而造成版面不簡潔的話,可以考慮使用「**」來拆解一個裝有參數名與值的dict。

**第一招-拆解Dict 原諒我使用這麼中二的小標題XDD 直接看實例應該就能懂了:dt={'sep':'#','end':'\n\n'}print('hello','world',**dt)#等同於print('hello','world',sep='#',end=& 繼續閱讀 [C]每天來點字串用法(5)-strcat()、strncat() 2月24,2018 好的,不知道又過了幾天(廢),終於要來到第5篇了。

strcat()、strncat():串接字串 所屬標頭檔: 函式宣告:char*strcat(char*dest,constchar*src);char*strncat(char*dest,constchar*src,size_tcount); 看到這熟悉的命名,該不會跟strcpy()、strncpy()那組函式很像吧?沒錯,所以按照上次的慣例,我們先來看看strcat()。

 strcat()有兩個參數,分別是dest和src,而這個函式的功用是將src接到dest後面,再回傳dest指向的字串。

那你可能會問:那原本dest的'\0'字元會跑去哪呢?答案是會被src的第一個字元(也就是src[0])所取代,並在最後面補上一個'\0'來當做新字串的結束字元。

 看到名字多了一個n的函式,你可能會猜,是不是這個strcat()也會造成緩衝區溢位的問題呢?沒錯,所以接下來要介紹比較推薦的函式:strncat()。

 如果有看過之前那一篇的話,應該都已經知道這個函式要怎麼用了,他會多接受一個整數,作為控制最多串接的字元數。

不過這裡的機制跟strcpy()有點不一樣:     1)無論如何都會在最後放一個'\0',而這個'\0'並不受count的限制。

也就是說,真正串接字元數的最大值其實是count +1。

 讓我們來看看他們的使用範例:#include#includeintmain(){//strcatchars1[8]="hi",s2[8]="sky";strcat(s1,s2);printf("%s\n\n",s1);//strncatchars3[8],s4[8];scanf("%s%s&q 繼續閱讀 天ほし 瀏覽簡介 分類 日常-短談3 日常-預告1 程式設計-天天來一點小技巧7 程式設計-資料庫-SQL-sqlite4 程式設計-演算法-搜尋-樹、圖3 程式設計-C-字串7 程式設計-C#-好用類別1 程式設計-Cpp5 程式設計-Lua6 程式設計-Python9 歌詞翻譯-日文2 顯示更多 顯示較少 網誌存檔 2021 1 三月 1 2020 1 一月 1 2019 7 九月 1 七月 3 五月 3 2018 15 九月 1 七月 2 五月 1 四月 2 三月 2 二月 7 [C]每天來點字串用法(5)-strcat()、strncat() [C]每天來點字串用法(4)-strchr()、strrchr()、strstr() [C]每天來點字串用法(3)-fromconstchar*tochar* [演算法][C++/Python]當DFS遇上排列 [C]每天來點字串用法(2)-strcpy()、strncpy() [C]每天來點字串用法(1)-strlen() [C]每天來點字串用法(基本篇) 2017 4 六月 2 二月 1 一月 1 2016 4 十二月 4 顯示更多 顯示較少 檢舉濫用情形



請為這篇文章評分?