在线时间 0 小时 最后登录 2005-9-21 注册时间 2004-4-27 听众数 1 收听数 0 能力 0 分 体力 1027 点 威望 0 点 阅读权限 40 积分 385 相册 0 日志 0 记录 0 帖子 153 主题 43 精华 0 分享 0 好友 0
升级 28.33%
该用户从未签到
国际赛参赛者
< >不知道大家有没有我这种体验.大家先看看下面这段代码:</P>
5 [: q) f0 h, q. X < >int fp=_wopen(L"Hello.dat",O_BINARY | O_CREAT | O_TRUNC | O_RDWR);
0 }+ V% _* z6 Y4 s if(fp==-1) return;4 z; ^: E6 G0 \* D) e
write(fp,L"123中国人",wcslen(L"123中国人"));, H, t$ z% w& u+ t. L9 z- w' M5 }' x
close(fp);: E% J3 J2 Q# B1 ?$ ?) E
- y7 L# E+ Q( m# o( V/ Z4 y
上面这段代码不知道大家看出什么BUG来了.如果大家看不出毛病也不足为怪,因为这是我们的习惯导致了我们的错误产生.
# H( ^8 Q4 d, U8 w" {1 n + H/ \1 l# x4 U# [) n, g4 `
先让我来分析一下write吧.下面是write的原型:1 f3 \$ b3 k& ]
int write( int <I>handle</I>, const void *<I>buffer</I>, unsigned int <I>count</I> );
8 H0 |4 Q" e; l( b b% a ; G4 n( T1 v& D. j( c' Y( s. `% U
参数:8 O- p4 I$ p/ B6 M5 h, I: {
handle 已打开或已创建的文件句柄: {6 J& g+ {9 K* ^4 J
buffer 待写入的数据
* j+ e) ^3 ]' B+ N; @0 e count 待写入的数据大小
' F# _- s! j- w8 k* L # D. I3 n- U' J( h E
现在分析为什么上面的那代码有bug,其实主要问题就在一个buffer,和count.
& r) x T: b$ B. e A J 如果我们写入一个Ansi字符串,上面的代码改成相应的形式确实没有错. {( \) o6 j/ q' T6 p
但如果是写入一个宽字符串,那么上面的代码就不严格.原因就在于count.! P, s4 o9 G, S5 G; u
0 S9 J# {9 X6 b Y 我们首先看一下strlen和wcslen,如果使用strlen,一般情况下,我们直接作为字符串的长度,
' `' u% s' m Y 而使用wcslen,你会发现,得出的不是字符串的长度而是字符的个数.' }9 P5 B* }+ f# r" }
6 ?" j" }5 t8 ]3 }) V 这就是问题的所在.一般情况下.char的长度是1,这是用sizeof(char)运算出来的结果.: D" ~ N/ N/ G' c1 l# V
len=strlen(str)*sizeof(char);而我们一般情况下,都只用strlen(str)来等价,这就是平时的习惯.
3 Q! J# S( b% E9 Q$ j 正是由于这个习惯所引来的问题,这个习惯并不适用于宽字符串.因为wcslen(str)*sizeof(wchar_t)并不等于wcslen(strl).这就是习惯所引起的错误.1 b8 }' s6 }) F' A# ]: f3 B
& v/ @/ j$ o1 s 说到这里我想大家都明白了.我在这里把这种习惯称之为不良习惯.所以大家以后在计算字符串长度的时候,千万不能简而简之,一定要len=strlen(str)*sizeof(char),len=wcslen(str)*sizeof(wchar_t).
+ C1 Q1 _* x2 a4 C) c/ K 不要再犯这种习惯性的低级错误.(在下就犯了这种错误.大家都可怜我吧!).</P>/ w( c' d% t3 S5 Z! c, `3 Z. b
[此贴子已经被作者于2004-11-26 9:50:40编辑过]
zan