数学建模社区-数学中国
标题:
关于wcslen的一个错觉!
[打印本页]
作者:
xShandow
时间:
2004-11-26 09:45
标题:
关于wcslen的一个错觉!
<
>不知道大家有没有我这种体验.大家先看看下面这段代码:</P>
4 A3 ]5 {( w g
<
>int fp=_wopen(L"Hello.dat",O_BINARY | O_CREAT | O_TRUNC | O_RDWR);
- ?* c& R8 T$ m l2 |: Q
if(fp==-1) return;
" ]7 A# Y& r$ z `6 P' T
write(fp,L"123中国人",wcslen(L"123中国人"));
- p: ]. e) k* [* I! P
close(fp);
( Z, W6 Y4 E7 A+ |0 \6 a2 Z
4 X0 k# e$ w+ {% v
上面这段代码不知道大家看出什么BUG来了.如果大家看不出毛病也不足为怪,因为这是我们的习惯导致了我们的错误产生.
$ E3 f2 P, K5 f8 |) Y1 e
- b" J h$ O% g; W$ b' h
先让我来分析一下write吧.下面是write的原型:
) j# u+ Z9 O4 \/ i& K H y, B! h% K. l
int write( int <I>handle</I>, const void *<I>buffer</I>, unsigned int <I>count</I> );
- y! d5 B) P/ }4 M, Z) _! y, O, s; i# m6 ~
! [1 t, O" P: T, v& p
参数:
* |3 V& j, U* S' G+ f/ w3 J
handle 已打开或已创建的文件句柄
: p4 O) Z* Z$ K5 B5 ` @
buffer 待写入的数据
. k$ h l8 F5 X5 S
count 待写入的数据大小
) @& c t# e5 |! x9 @$ t
* y9 T% Y& ^ h0 I
现在分析为什么上面的那代码有bug,其实主要问题就在一个buffer,和count.
# F! {6 F, k" @7 N$ a
如果我们写入一个Ansi字符串,上面的代码改成相应的形式确实没有错.
% i# s$ a4 ~) \, e
但如果是写入一个宽字符串,那么上面的代码就不严格.原因就在于count.
. k3 @( X, \) N2 m- V% j
/ ^3 `4 Y) C& W
我们首先看一下strlen和wcslen,如果使用strlen,一般情况下,我们直接作为字符串的长度,
/ J; }( U' V; T4 O
而使用wcslen,你会发现,得出的不是字符串的长度而是字符的个数.
' G* w+ G$ h3 b5 s! C$ a d
, k- u/ a* l; `" {. Z' P* _
这就是问题的所在.一般情况下.char的长度是1,这是用sizeof(char)运算出来的结果.
+ H/ J% e, \' @
len=strlen(str)*sizeof(char);而我们一般情况下,都只用strlen(str)来等价,这就是平时的习惯.
+ q% q* _$ @/ s( q5 s2 @( T2 H# i
正是由于这个习惯所引来的问题,这个习惯并不适用于宽字符串.因为wcslen(str)*sizeof(wchar_t)并不等于wcslen(strl).这就是习惯所引起的错误.
% [$ }8 ]' F" b2 u3 ~
0 z `/ `6 ]* [$ j& X
说到这里我想大家都明白了.我在这里把这种习惯称之为不良习惯.所以大家以后在计算字符串长度的时候,千万不能简而简之,一定要len=strlen(str)*sizeof(char),len=wcslen(str)*sizeof(wchar_t).
& R# |3 X$ u, S" z" J
不要再犯这种习惯性的低级错误.(在下就犯了这种错误.大家都可怜我吧!).</P>
3 Y! U. _$ J1 M
[此贴子已经被作者于2004-11-26 9:50:40编辑过]
作者:
ilikenba
时间:
2004-12-2 15:50
欧!我也是一直那样想当然的用了!
作者:
xShandow
时间:
2004-12-2 17:55
我被这个错误折磨了好半天。
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5