数学建模社区-数学中国
标题:
关于wcslen的一个错觉!
[打印本页]
作者:
xShandow
时间:
2004-11-26 09:45
标题:
关于wcslen的一个错觉!
<
>不知道大家有没有我这种体验.大家先看看下面这段代码:</P>
2 `! h6 R! _( F, b; W- U. G
<
>int fp=_wopen(L"Hello.dat",O_BINARY | O_CREAT | O_TRUNC | O_RDWR);
! Q/ w1 }5 P. |# }: X; Z, E
if(fp==-1) return;
3 p9 n* T; O7 _: A5 N, S
write(fp,L"123中国人",wcslen(L"123中国人"));
: N4 B% f" k( Q# L. [2 ~% A
close(fp);
" h$ \: r9 _* a
G1 ]# X+ G/ Q5 P3 o2 w2 h$ g
上面这段代码不知道大家看出什么BUG来了.如果大家看不出毛病也不足为怪,因为这是我们的习惯导致了我们的错误产生.
. P2 ^' r2 x1 [3 X3 r) H% I% h; f
/ ^: h' x- G# U# M
先让我来分析一下write吧.下面是write的原型:
) i0 l2 `# [' d/ H8 {+ L$ b
int write( int <I>handle</I>, const void *<I>buffer</I>, unsigned int <I>count</I> );
, i# e9 \9 _& o2 }( N8 |; P- r0 r4 z
/ t" _! t H- \( C8 _
参数:
% Z% ?+ u/ j7 O5 F9 L+ v( P9 M: `
handle 已打开或已创建的文件句柄
/ s9 {% F# v: R# C! z4 H9 g
buffer 待写入的数据
' \$ u, r) c9 X. S8 H- l* `/ V
count 待写入的数据大小
2 Q' H1 }. O2 P
7 L8 G6 u; Q! k& N0 S4 K' L
现在分析为什么上面的那代码有bug,其实主要问题就在一个buffer,和count.
3 x/ Z6 V/ i C6 |1 Y8 |
如果我们写入一个Ansi字符串,上面的代码改成相应的形式确实没有错.
. P2 C: z0 i: a" u
但如果是写入一个宽字符串,那么上面的代码就不严格.原因就在于count.
( M0 ^4 r9 A" D6 X+ y
! I/ \2 b+ G. J/ U# X9 L
我们首先看一下strlen和wcslen,如果使用strlen,一般情况下,我们直接作为字符串的长度,
* }5 ^/ |) E, ?; S% a7 g) u
而使用wcslen,你会发现,得出的不是字符串的长度而是字符的个数.
: L/ N6 p8 N6 o9 P2 j- W- v
/ L' Y- G# ~# ?& E! i* K
这就是问题的所在.一般情况下.char的长度是1,这是用sizeof(char)运算出来的结果.
' Q3 c, `" S. Z( n: I
len=strlen(str)*sizeof(char);而我们一般情况下,都只用strlen(str)来等价,这就是平时的习惯.
3 O: j! z G4 W3 I; B$ u; a
正是由于这个习惯所引来的问题,这个习惯并不适用于宽字符串.因为wcslen(str)*sizeof(wchar_t)并不等于wcslen(strl).这就是习惯所引起的错误.
) `) N6 @5 C9 _- [& _& z V4 J
1 d- ~5 P3 p1 x2 R4 c' ?& `% G
说到这里我想大家都明白了.我在这里把这种习惯称之为不良习惯.所以大家以后在计算字符串长度的时候,千万不能简而简之,一定要len=strlen(str)*sizeof(char),len=wcslen(str)*sizeof(wchar_t).
9 n: E v5 q! f; d. I" Y% X
不要再犯这种习惯性的低级错误.(在下就犯了这种错误.大家都可怜我吧!).</P>
/ H7 C+ k1 c' \5 f, k, @
[此贴子已经被作者于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