数学建模社区-数学中国

标题: 关于wcslen的一个错觉! [打印本页]

作者: xShandow    时间: 2004-11-26 09:45
标题: 关于wcslen的一个错觉!
<>不知道大家有没有我这种体验.大家先看看下面这段代码:</P>
1 C  d( s4 m  [( u* a( O<>int fp=_wopen(L"Hello.dat",O_BINARY | O_CREAT | O_TRUNC | O_RDWR);
4 h: B  n2 k' r; Y* @2 Lif(fp==-1) return;
- R& j0 E7 _& y# ywrite(fp,L"123中国人",wcslen(L"123中国人"));
5 E, I' T) T/ ?+ Q) l9 a9 Lclose(fp);; ~5 P2 B+ p! [: ^

$ ?; J2 u" \2 i+ D, Y! L; i3 P上面这段代码不知道大家看出什么BUG来了.如果大家看不出毛病也不足为怪,因为这是我们的习惯导致了我们的错误产生.
7 o6 Y* a2 {, V9 X( j: S9 i5 b4 Q
先让我来分析一下write吧.下面是write的原型:/ h1 s9 b% o. U- k; w! @
int write( int <I>handle</I>, const void *<I>buffer</I>, unsigned int <I>count</I> );# t! J. m# `0 V3 B' V+ b- j
$ q1 V9 S6 F0 N% U8 V( [
参数:
1 H* b. S5 P  t4 }% i0 Xhandle   已打开或已创建的文件句柄
: q1 R8 g( l8 j# Q, O* B/ k7 _buffer     待写入的数据* }* R; Y9 h6 y6 |8 z1 V% l
count     待写入的数据大小
5 m1 `, A" s2 n, K$ u% c; `) K3 q/ ]1 I, f/ y
现在分析为什么上面的那代码有bug,其实主要问题就在一个buffer,和count.
- Q3 u" \9 U7 E" Z9 A如果我们写入一个Ansi字符串,上面的代码改成相应的形式确实没有错.
% i# M8 i- x4 p$ W但如果是写入一个宽字符串,那么上面的代码就不严格.原因就在于count.* k# D( Z( S% n5 l' ?

1 U* M* _9 M0 b  p% C% R我们首先看一下strlen和wcslen,如果使用strlen,一般情况下,我们直接作为字符串的长度,
: |" Q; y, E& A. r而使用wcslen,你会发现,得出的不是字符串的长度而是字符的个数.! t8 d. \6 b' K: ?% N
( f* g- ^) s+ K" n
这就是问题的所在.一般情况下.char的长度是1,这是用sizeof(char)运算出来的结果.5 p: @  X1 K  \# N* ~6 L
len=strlen(str)*sizeof(char);而我们一般情况下,都只用strlen(str)来等价,这就是平时的习惯.
+ X. `' F7 D3 l6 N正是由于这个习惯所引来的问题,这个习惯并不适用于宽字符串.因为wcslen(str)*sizeof(wchar_t)并不等于wcslen(strl).这就是习惯所引起的错误.2 b( ~+ t- z( p3 ]! Q1 u* T  w
0 o/ W' h0 I4 |& q1 Q# G8 {
说到这里我想大家都明白了.我在这里把这种习惯称之为不良习惯.所以大家以后在计算字符串长度的时候,千万不能简而简之,一定要len=strlen(str)*sizeof(char),len=wcslen(str)*sizeof(wchar_t).2 \4 r8 c/ q" X$ |
不要再犯这种习惯性的低级错误.(在下就犯了这种错误.大家都可怜我吧!).</P>& k+ n7 W  f8 Q4 V
[此贴子已经被作者于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