VB的instr函数不准确的原因

gotohl 2011-11-30 12:53:00
我的程序大致过程是这样的:
1.打开一个文章列表的网页,逐个读出标题,再用每个标题在标题库TitleFile里用instr函数查找,当返回0,则认为此标题是新标题,并在 TitleFile 后追加此标题,添加方式是 TitleFile = TitleFile & vbCrLf & Title(iTeam);
2.当返回大于0,则认为是重复标题,则不添加。

问题:函数常常不能准确的判断是否重复,明明已经重复了,但是instr依然返回0,请问问题有可能出在哪里?如果我这个方案不可行,是否有更科学的办法。
补充:由于数据量比较大,TitleFile字符串比较长,大约几千行标题,保存成txt文件也有50kb以上。

大致代码如下:


If InStr(TitleFile, Title(iTeam)) > 0 Then
(重复标题的处理...)
Else
TitleFile = TitleFile & vbCrLf & Title(iTeam)
End If
...全文
291 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
无·法 2011-12-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 worldy 的回复:]

TitleFile = TitleFile & vbCrLf & Title(iTeam)
是一种非常低效的操作,因为VB的文本链接 & 操作 比如 a=b & c 时,需要计算出b,c的长度,然后分配一块容纳lenb(b)+lenb(c)的内存a,再将b拷贝到a、c拷贝到a,单独一个&效率没有什么大不了,但是,当使用循环进行连接,那么,拷贝的消耗完全超……
[/Quote]我只是在楼主代码基础上给出点建议说明问题所在。

你说的是有道理,效率什么的要看具体应用,看楼主的应用场景估计就是采集网页用的,下载网页或者用webbrowser打开这才是最大的时间成本,有时甚至加上延时,取得具体什么title的话离不开instr之类的字符串函数操作,用正则也得引入个外部对象,这个条件判断里加个instr 连接字符串什么的相对来说只能算是九牛一毛,所以完全不需要考虑。 如果实在追求效率高的话用更底层的c+asm实现,可以指导一下。
worldy 2011-12-01
  • 打赏
  • 举报
回复
TitleFile = TitleFile & vbCrLf & Title(iTeam)
是一种非常低效的操作,因为VB的文本链接 & 操作 比如 a=b & c 时,需要计算出b,c的长度,然后分配一块容纳lenb(b)+lenb(c)的内存a,再将b拷贝到a、c拷贝到a,单独一个&效率没有什么大不了,但是,当使用循环进行连接,那么,拷贝的消耗完全超出你的想象!
同时,instr需要在对源字符串逐个对齐进行比较,相对于数组比较(开头字符对齐比较),又是一个低效的操作;

因此,2L给你的代码应该是一个比较有效率的操作方式!
无·法 2011-11-30
  • 打赏
  • 举报
回复
[Quote=引用楼主 gotohl 的回复:]
我的程序大致过程是这样的:
1.打开一个文章列表的网页,逐个读出标题,再用每个标题在标题库TitleFile里用instr函数查找,当返回0,则认为此标题是新标题,并在 TitleFile 后追加此标题,添加方式是 TitleFile = TitleFile & vbCrLf & Title(iTeam);
2.当返回大于0,则认为是重复标题,则不添加。

问题:函数常常不……
[/Quote]明摆着的是你代码的问题。早上遇到个问题,按F8一步步调试还是没发现,最后决定查看它的二进制数据,发现最后一个字符的asc码竟然是13,也就是不小心加了个换行符。
所以你把认为有问题的变量仔细检查下。比如空格啊,全角空格啊半角空格啊,以及连续空格在html中是表示为 的,这些只有单步调试了,而不是肉眼简单一看就说诊断是instr的问题。

你的代码基本也是不完善的,打个比方,有这么几行abc、ab,而你获得了一个新的标题为a,那么会被检测为存在。修改如下:
 If InStr(vbcrlf & TitleFile,vbcrlf &  Title(iTeam) & vbcrlf ) > 0 Then'加上前后的回车符这样就避免了字符串相包含的问题
(重复标题的处理...)
Else
TitleFile = TitleFile & vbCrLf & Title(iTeam)
End If
dafu2003 2011-11-30
  • 打赏
  • 举报
回复
。。。。。却不怀疑自己。。。。。。。
dafu2003 2011-11-30
  • 打赏
  • 举报
回复
楼主连这都怀疑。。。。。。。。
贝隆 2011-11-30
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yachong 的回复:]
顶楼上
这种基本的函数不要去怀疑
看看是不是字符串里面包含了全角空格之类的字符,这个用trim去不掉的。
[/Quote]
+1
不过,楼主的思路应该说有一个缺陷,他没有考虑到字符串是有一定的容量限制的,当内容超出限制后程序势必出错,怎么办?

所以最好的办法还是实用数组。效率并不低。
yachong 2011-11-30
  • 打赏
  • 举报
回复
顶楼上
这种基本的函数不要去怀疑
看看是不是字符串里面包含了全角空格之类的字符,这个用trim去不掉的。
chinaboyzyq 2011-11-30
  • 打赏
  • 举报
回复
注意中英文标点的区别,还有是否含回车符、换行符等等,还有instr比较方式等。
别把问题想成是程序函数的问题,多想想你自己的问题。
worldy 2011-11-30
  • 打赏
  • 举报
回复
Dim Title() As String
Dim TitleFile As String

Private Sub Command1_Click()
Dim i As Long
Dim j As Long
Dim MaxItem As Long
Dim s As String
Dim Temp() As String
Dim MaxNew As Long

MaxItem = UBound(Title)
ReDim Temp(MaxItem)

Temp(0) = Trim(Title(0))

For i = 1 To MaxItem
s = Trim(Title(i))
If s <> "" Then
For j = 0 To MaxNew
If s = Trim(Title(j)) Then
GoTo Found
End If
Next
MaxNew = MaxNew + 1
Temp(MaxNew) = s
End If
Found:
Next

ReDim Preserve Temp(MaxNew)

TitleFile = Join(Temp, vbCrLf)
End Sub
  • 打赏
  • 举报
回复
不是不准确吧。把你认为不准确的TitleFile, Title(iTeam)放出来看看……

1,502

社区成员

发帖
与我相关
我的任务
社区描述
VB 网络编程
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧