CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VB >  API

GetPrivateProfileString和LEFT综合的问题

楼主jautomn(Oce@n Chu)2005-01-01 11:47:34 在 VB / API 提问

[ABC]  
  DEF=中华人民共和国  
   
  有时DEF=中华人ABC民共和国  
   
  有时DEF=ABCDEFG  
   
  如果才能不管键值是单字节还是双字节都能正确读取.  
   
  用LEFT取得的数据不是后面有chr(0)的字符就是有些是乱码.  
   
          n   =   GetPrivateProfileString("ABC",   "DEF",   "123",   keykey,   256,   App.Path   &   "\setup.ini")  
          str   =   LeftB(keykey,   n)  
  问题点数:30、回复次数:9Top

1 楼cindytsai(笨笨的蔡鸟)回复于 2005-01-01 12:23:41 得分 3

帮顶一下Top

2 楼asmgirl(过期菜鸟)回复于 2005-01-01 13:15:50 得分 3

学习Top

3 楼jautomn(Oce@n Chu)回复于 2005-01-01 14:49:30 得分 0

太好了,自己试出来了,分享  
   
  abc   =   StrConv(LeftB(StrConv(keykey,   vbFromUnicode),   n),   vbUnicode)  
   
  Top

4 楼VBAHZ(凌云(E文词汇量580))回复于 2005-01-01 15:20:01 得分 8

那是因为你没有事先给keykey分配内存空间(API就是这样死板)  
   
  keykey   =   String(256,   0)  
  N   =   GetPrivateProfileString("ABC",   "DEF",   "123",   keykey,   256,   App.Path   &   "\setup.ini")  
  str   =   LeftB(keykey,   N)  
  ===============  
  str=中华人民共和国  
   
  另外,API的定义需要注意:  
  Private   Declare   Function   GetPrivateProfileString   Lib   "kernel32"   Alias   "GetPrivateProfileStringA"   _  
      (ByVal   lpApplicationName   As   String,   ByVal   lpKeyName   As   Any,   _  
          ByVal   lpDefault   As   String,   ByVal   lpReturnedString   As   String,   _  
          ByVal   nSize   As   Long,   ByVal   lpFileName   As   String)   As   Long  
   
  Top

5 楼homezj(小吉)回复于 2005-01-01 20:50:26 得分 8

呵呵,这种问题在字符串中有中英文混合的情况下,不可避免,因为API返回的是ANSI字符长度,这个长度比Len的取值长,比LenB的取值短。  
   
  StrConv是常用的办法,不过这种方法,还是有一点小局限性:这也是我以前无意中发现的。  
  当用户是中文系统,可控制面板的区域设置中,却指定了一个非中国区域,如:美国。这在国外华侨中非常普遍,当然还有一些D版XP也是这样。  
  你会发现这样的系统中,虽然看不出中文显示有什么异样,但用StrConv处理过的中文就会是乱码,因为其对非Unicode编码的默认字符集不是GB。  
   
  若想兼容性更好,最好放弃API的返回值,自己判断长度,我给你一个通用函数。  
  Public   Function   GetIni(sec   As   String,   key   As   String,   file   As   String,   Optional   BufLen   As   Long   =   1024)   As   String  
          Dim   i   As   Long,   s   As   String,   j   As   Long  
          s   =   Space(BufLen)  
          i   =   GetPrivateProfileString(sec,   key,   "",   s,   BufLen,   file)  
          If   i   >   0   Then  
                  s   =   replace(RTrim(s),   Chr(0)   &   Chr(0),   "")  
                  If   Right(s,   1)   =   Chr(0)   Then  
                          GetIni   =   Left(s,   Len(s)   -   1)  
                  Else  
                          GetIni   =   s  
                  End   If  
          End   If  
  End   Function  
  Top

6 楼VBAHZ(凌云(E文词汇量580))回复于 2005-01-01 21:38:48 得分 8

效率太低,最坏的情况(在执行API后)从源码来看有15个步骤6行语句:  
  1、判断I值  
  2-3、转换字符Chr(0)   Chr(0)  
  4、合并字串Chr(0)&Chr(0)  
  5、RTrim(S)  
  6、""(抄来的:""这里VB做了很多工作,首先,VB在编译时,把””当成了一个常量,它必须为这个空字符串内部申请一个变量。当EXE文件加载后,也得把它设定一个地址,虽然它什么都不代表  
  是一个   00   00   00   00   00   00   这样的字符串,它需要6个字节(四个头字节和2个尾字节)  
  然后当看到这句时再把第五个字节的地址值传回。所以,虽然你只是信手写了一个””,结果VB多作了很多工作。6个字节虽然不多,但是在一个大工程里,大家都到处写“”,那么也是很可观的一笔开销。)  
   
  7、替换(个人认为这是最没效率的一句,既然结果我们不会要Chr(0)的字符,替换它干啥?况且不兼容VB5)  
  8、赋值回S  
  9、Right(S,1)  
  10、转换字符Chr(0)  
  11、比较是否为Chr(0)  
  12、Len(S)  
  13、减一  
  14、Left(S,)  
  15、GetIni赋值  
   
  虽然俺不懂汇编,但听说VB中效率最低的就是字符串操作,所以应该尽量减少吧?俺认为能减少源码的执行步骤,最终生成的代码总是效率高一点吧?  
  API认为Chr(0)是字符串的终结,而VB中也不会显示Chr(0),INI文本中不应该出现Chr(0)  
  那在调用前就申明为Chr(0)  
  s   =String(BufLen,0)  
  I=.....  
   
  GetINI=Left(S,   InStr(S,vbNullChar)   -   1)  
  就这一句(4个步骤)完事!  
  Top

7 楼jautomn(Oce@n Chu)回复于 2005-01-17 13:09:14 得分 0

我都看不懂,谢谢大家的关心,都加分,分是少了点,一点心意。问题已解决了。就用这个。  
  abc   =   StrConv(LeftB(StrConv(keykey,   vbFromUnicode),   n),   vbUnicode)Top

8 楼homezj(小吉)回复于 2005-01-17 14:24:52 得分 0

今天才看到这个贴子!  
  To:VBAHZ(凌云(E文词汇量580))    
  很高兴有人对那段代码效率提出看法,我也估计很多人会对那个函数不理解。Left(S,   InStr(S,vbNullChar)   -   1)是提取API返回值最常用方法,我当然不会不知道,你把问题想简单了!  
   
  Ini文件有个很重要的功能,就是返回一个段下的全部键名,而多个键名就是用chr(0)分割的,若用查找第一个Chr(0)的办法,是得不到多个值的。这种情况还常见于,OpenFile对话框返回多个值。  
   
  所以函数中只能去掉返回值的未尾所有的Chr(0),而不能去串中间的Chr(0)。这类问题见多了,就会理解的。Top

9 楼VBAHZ(凌云(E文词汇量580))回复于 2005-01-20 03:05:10 得分 0

今天才看到这个贴子!  
  To:homezj(小吉)  
  很高兴有人对那段代码提出看法,你把问题想复杂了!  
   
  用INI文件,几乎有90%以上的时候是要返回单个键的值,(当然,返回全部键还是要用到的,这时候往往要大批量的处理,所以效率更重要)  
  API函数基本以C来写的,所以大多以CHR(0)分割,但这不适合VB,VB的字符操作就是慢!若返回大段的字符再分割CHR(0)就更慢了,还不如自定义函数,找到段名,一次读入全部文本数据快。(懒的写代码的人除外,那叫——用户)  
  接下来,若要在Text中显示,直接转过去就行,无需再拼接回车换行符,若要分解,也只不过以vbCrlf来分解而已。  
  要知道INI文件本身就是定义严格的以回车换行符分割的文本行文件,跳过API的载入读取分解拼接(重新以Chr(0)拼接)过程,经过实践,用VB自己的Line   Input能更高效率的处理它。(指大段的文本行)  
   
  Top

相关问题

  • 关于IIS和flash的综合问题
  • #### 下拉框和输入框的综合 ####
  • 请教:鼠标拖拽和搜索的综合问题??
  • ▲▲▲200分 留言板“主题”和“回复”综合显示的问题!200分▲▲▲
  • “类强制转换”和“数据类型强制转换”综合问题
  • 综合问题~急~~
  • 50分!GetPrivateProfileString和WritePrivateProfileString的问题,真奇怪!
  • GetPrivateProfileString不能用
  • 请各位帮忙,关于最大值和综合查询的问题?40分相送!
  • 一个综合问题,,?????

关键词

  • 字符
  • 函数
  • 文本
  • 代码
  • 文件
  • vb
  • 中文
  • keykey
  • chr
  • getini

得分解答快速导航

  • 帖主:jautomn
  • cindytsai
  • asmgirl
  • VBAHZ
  • homezj
  • VBAHZ

相关链接

  • Visual Basic类图书
  • Visual Basic类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo