2010-02-24 39 views
4

我在ANSI C中编写命令行程序来解析Quake 2映射文件来报告使用了多少实体和纹理。我的开发机器是MacBook。我正在测试OS X Snow Leopard(32位),Windows XP(32位)和Vista(64位)以及Ubuntu 9.10(32位)。如何在程序崩溃之前检测到文本文件是否损坏?

我在Vista上发生了一个崩溃的bug,其中程序会挂上某个映射文件。花了一段时间才发现它不是程序,而是地图文件本身。我没有注意到文本文件的任何异常。重新打开并保存地图文件修复了该问题。

我的代码将整个映射文件加载到内存中,使用strtok()使用'\ n'分隔行,分析每行,并将数据加载到单链接列表中进行处理。有没有办法来检测地图(文本)文件是否损坏?

最简单的非编程解决方案是添加一个包含问题和解决方案的FAQ文件。

+4

错误的输入不应该使程序崩溃,所以答案是“是”。至于如何,它取决于您的程序或您使用的库中的特定错误。代码崩溃的代码片段将是一个开始。当你“重新打开并保存”时,文件是否改变? – 2010-02-24 06:26:03

+1

为什么程序崩溃? (Windows上的线路终止使用\ r \ n,在* nix上它是\ n,这可能是您的应用程序的问题吗?) – 2010-02-24 06:27:14

+0

在我上次的编辑会话中,编辑器崩溃了,应该不会将任何数据保存到映射文件。当我加载并在编辑器中重新保存地图文件并重新编译游戏文件时,它工作正常。地图文件有些不同,但我不确定是什么。我不认为“\ r \ n”与“\ n”是一个问题。该程序运行良好,直到遇到此文件。 – 2010-02-24 06:43:11

回答

0

我想我修复了这个错误。我采取了一些步骤来到那里,测试进行得很顺利。

  • 新增 - 转换为我的GCC调试组合。这报告了一些有用的警告,并没有如此有用的警告。大多数情况下,向变量类型和一些次要(int)强制类型添加无符号。
  • 尽管我的数据结构具有正确的类型(即unsigned long int),但将所有内容相加的输出变量都是错误的类型(即int)。重新检查所有我的变量类型,以确保它们全部匹配。
  • 增加了一个检查,如果该文件有零或负字节大小停止程序出现错误。
  • 添加了一个检查,如果数据列表中有零节点(即解析返回无效匹配),以便通过文件没有可用数据的消息来暂停程序。

我现在只剩下解析函数了。如果地图文件有损坏或损坏,那么“数据”最终会被输出。垃圾进出口(GIGO)仍然是一个因素。稍后再回顾一下。我的程序的发布版本可以找到here

2

当你阅读每一行解析它,以确定它是否有效。如果你的方法失败了,你可以简单地让用户知道数据已损坏,但你仍然有一个优雅的退出。

+0

我不确定碰撞发生在哪里。它的行为方式类似于之前在Vista(64位)上的崩溃问题,我在数据结构中使用“unsigned int”来计算引用数量(即38564)。我将其改为“unsigned long int”来修复这个bug。除非文件被破坏,行被解析并计数超过long int。嗯... – 2010-02-24 06:53:11

+0

你确定你会溢出吗?可能是另一个问题?例如,对象与您正在创建的值相关的不兼容。 – lkg 2010-02-24 11:09:10

0

使用解析器生成器工具,您可以轻松检测语法错误。

但是,即使语法正常,您也应该始终假定内容可能不正常。

例如,如果该文件格式如下:

  • N:条目数
  • 条目1
  • 条目2
  • ...
  • 结束条件

你的代码不应该只分配n个大小的数组,并将条目读入数组直到结束条件。相反,您应该验证n条记录是否被实际读取(在这种情况下,从未读取超过n条记录以避免溢出)。

因此,设计代码,以便它不会盲目信任输入。

相关问题