中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > .NET平台
除虫随记
作者:未知 时间:2005-07-20 14:21 出处:VC知识库 责编:chinaitpower
              摘要:除虫随记

除虫随记


作者:Abbey


源代码下载:IPPortAbstractor.rar(8KB)


摘要 本文讲述了本人在编写一个IP:Port提取器过程中发现 Bug 并最终排除它们的过程,并解释了原理。

关键字 VC# 正则表达式 调试


  我最近在看正则表达式,加之本人又是一个 CSer,于是想着利用正则表达式从文件中提取 IP:Port 这样的服务器地址,于是便有了昨天写的这个项目(不要被它的项目名称迷惑,我本来要做个关机程序 Shutdown 的,后来才改做这个 IPPortAbstractor 的)。先看看它的界面吧。
 


接着我完成了最初的代码,在调试过程中发现了以下几个Bug:

1、ProcessMatch() 成员中:
  Bug-1:下面这样并不会引发编译错误,但是 StringBuilder 数组的数据元素需要另行 new ,因此在运行时会触发异常“源数组中至少有一个元素无法被向下转换到目标数组类型。”我想我是把 string 与 StringBuilder 看得太简单了。

textlineList.CopyTo(strArray);

正确的做法是利用循环,如下:

for (int i = 0; i< textlineList.Count; ++i)
strArray[i] = new StringBuilder((string) textlineList[i]);

  Bug-2:这样也不会引发编译错误,但会触发异常“指定的转换无效。”我看上面的转换都成功了,这里为什么就不行呢?不得其解,还请各位解释一下

matches = m_regexIPPort.Matches((string)textlineList[i]);

正确的做法是利用 object.ToString() 函数,如下:

matches = m_regexIPPort.Matches(textlineList[i].ToString());

2、buttonDelete_Click() 成员中
  Bug-3:在这里,我想把用户在 Listbox 中的选中行删除,最先用的是这样的 for 循环,结果会发生无法一次性将多个选中行删除的现象

for (int i = 0; i < listboxResult.SelectedIndices.Count; ++i)
{ 
	m_IPPortList.Remove(listboxResult.SelectedItems[i].ToString());
	listboxResult.Items.Remove(listboxResult.SelectedItems[i]); 
}      
  正确的做法如下,这也是我想到的最简单的办法了。 Bug 的产生原因在于 SelectedIndices.Count 在 Remove 操作后会发生变化,从而导致 i 的值发生变化,因此不能使用 for 循环。
while ((i = listboxResult.SelectedIndices.Count) > 0)
{				
	// 切记:下面两条语句顺序不能颠倒
	// listboxResult.Items.Remove 删除元素后将导致 m_IPPortList.Remove
	// 无法定位,也会触发异常“索引超出了数组界限。”
	m_IPPortList.Remove(listboxResult.SelectedItems[i-1].ToString());
	listboxResult.Items.Remove(listboxResult.SelectedItems[i-1]);				
}      
3、保存搜索结果时一系列的 Bug
  这里连续的 Bug 是项目中我最头疼的。本想在点击“退出”后弹出对话框,提示用户保存搜索结果。选择“是”进行保存,选择“否”直接退出,选择“取消”返回程序。最早 buttonExit_Click() 主要内容是这样的:
if (!IsSaved)
{
	result = MessageBox.Show("搜索结果还没有保存,是否进行保存?", "保存搜索结果",
				 MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
	switch (result)
	{
		case DialogResult.Yes:  //要保存
			buttonSaveResult_Click(sender, e);
			Close();
			break;
							
		case DialogResult.No:  //不保存
			Close();
			break;
		
		case DialogResult.Cancel: //返回程序,暂不退出
			break;
		
		default:
			break;
	}
}      
  结果当你点击窗口右上角的关闭按钮时没有提示,直接就退出了。于是我为 Form 生成了 Closing 事件的处理函数:
private void IPPortForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
	buttonExit_Click(sender, e);
}      
   这下退出时提示倒是有了,但是点击“取消”之后程序也退出了,而没有返回程序。于是把 buttonExit_Click() 的内容删除其中的 Close() 调用后放在 IPPortForm_Closing() 中,而在 buttonExit_Click() 中则调用 Close() 成员。
  之后发生的事就更好玩儿了:在保存结果时如果点击保存文件对话框的“取消”按钮,程序直接退出!点击保存提示对话框的“取消”程序也直接退出。这下真的头疼了!寻寻觅觅,终于让我发现 System.ComponentModel.CancelEventArgs 变量 e 中一个属性 Cancel 可用,设置其为 true 将导致该事件被取消,于是我把 case DialogResult.Cancel 分支改成这样:
e.Cancel = true;
break;      
   这下解决了点击保存提示对话框的“取消”程序退出的问题,但还是没有解决第一个问题:在点击保存提示对话框的“是”之后,再点击保存文件对话框的“取消”,程序还是直接退出了!想到这里,应该是保存对话框的返回值没有相应的判断,于是给 buttonSaveResult_Click() 添加了一个 else 分支:
else  ((CancelEventArgs)e).Cancel = true;      
   问题得到解决了,但又发现了另一个 Bug :点击“保存结果”按钮时在弹出的保存文件对话框中点击“取消”时,程序在上面这条语句处触发异常“指定的转换无效。”另一方面,如果是点击“退出”按钮来弹出这个保存文件对话框则不会触发这样的异常,想来想去,只有在程序关闭事件中设置一个标志 IsClosing (初始化为 false )了,于是 buttonSaveResult_Click() 的 else 分支改成了这样:
else  ((CancelEventArgs)e).Cancel = true;      
IPPortForm_Closing()的 case DialogResult.Yes 分支代码改成了这样:
else
{
	if (IsClosing)
		((CancelEventArgs)e).Cancel = true;
}      
IPPortForm_Closing()的case DialogResult.Yes分支代码改成了这样:
IsClosing = true;
buttonSaveResult_Click(sender, e);
break;      
   终于,我的这个 VC# 工程算是完成了。当然我没有使用 try-catch 语句块对可能的空间不足等异常进行处理。不过程序的功能上应该没有 Bug 了吧。希望大家也帮我找找。先打 CS 去了,菜鸟我的 ID: TANK---Bug 。如果遇到我千万别打我,请让我打死你吧!

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有