關於wcslen的一個錯覺

不知道大家有沒有我這種體驗.大家先看看下面這段代碼:</P>" T/ [+ ~$ V. ~; p' H4 E0 G
<>int fp=_wopen(L"Hello.dat",O_BINARY | O_CREAT | O_TRUNC | O_RDWR);
if(fp==-1) return;; J; |  c2 c1 V. r
write(fp,L"123中國人",wcslen(L"123中國人"));
close(fp);8 v9 p& F" X5 I$ H, e- G

上面這段代碼不知道大家看出什麼BUG來了.如果大家看不出毛病也不足爲怪,因爲這是我們的習慣導致了我們的錯誤產生.

先讓我來分析一下write吧.下面是write的原型:- _- R! V& O7 [$ B
int write( int <I>handle</I>, const void *<I>buffer</I>, unsigned int <I>count</I> );
4 s# o; |" a% h$ y# p4 J% r
參數:6 ^, o% A& C3 J
handle   已打開或已創建的文件句柄) T5 I5 ]* B; B7 X
buffer     待寫入的數據
count     待寫入的數據大小% }3 m9 V7 i# P7 J
* r( P" t  ?+ i% L: U& g
現在分析爲什麼上面的那代碼有bug,其實主要問題就在一個buffer,和count.
如果我們寫入一個Ansi字符串,上面的代碼改成相應的形式確實沒有錯.4 q9 q! u1 s9 O$ _0 p7 n$ j
但如果是寫入一個寬字符串,那麼上面的代碼就不嚴格.原因就在於count./ ^5 Z" y( e" W! E% `: e

我們首先看一下strlen和wcslen,如果使用strlen,一般情況下,我們直接作爲字符串的長度,8 W2 x! `# n0 T' c) g" s
而使用wcslen,你會發現,得出的不是字符串的長度而是字符的個數.
$ a0 z8 T5 i2 m8 A  `( ]
這就是問題的所在.一般情況下.char的長度是1,這是用sizeof(char)運算出來的結果.
len=strlen(str)*sizeof(char);而我們一般情況下,都只用strlen(str)來等價,這就是平時的習慣.; A' Q5 o; f! C' c* g3 }
正是由於這個習慣所引來的問題,這個習慣並不適用於寬字符串.因爲wcslen(str)*sizeof(wchar_t)並不等於wcslen(strl).這就是習慣所引起的錯誤.( A! a# t' x8 l, L# }1 o

說到這裏我想大家都明白了.我在這裏把這種習慣稱之爲不良習慣.所以大家以後在計算字符串長度的時候,千萬不能簡而簡之,一定要len=strlen(str)*sizeof(char),len=wcslen(str)*sizeof(wchar_t).
不要再犯這種習慣性的低級錯誤.(在下就犯了這種錯誤.大家都可憐我吧!)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章