Windows 程序设计6:错误码的查看

文章目录


前言

Windows 程序设计6:错误码的查看。


一、说明

有时写的代码单纯看是没有问题的,但是执行起来就会崩溃。因此要养成判断函数执行是否成功的习惯,除非这个函数根本判断不了。比如void Init()这样的函数是可能没办法进行判断的,这种函数一般是肯定会保证执行成功的。如果是自己封装的函数或者系统提供的API函数有时就可以进行判断。

对于自己封装的函数或者系统提供的API函数,如果不能保证100%成功,一般都会通过返回值或者参数返回的形式来判断函数是否执行成功。

所以,我们在使用一个函数的时候,要对他执行后返回的状态进行判断,否则默认函数执行成功,程序继续往下执行的话,很有可能造成程序的崩溃,而且还找不到程序崩溃的问题。

二、使用GetLastError找到错误的原因

使用函数GetLastError找到执行的错误信息,函数原型

cpp 复制代码
DWORD GetLastError(VOID);

没有参数,返回值是DWORD双字的整型,表示错误码的值。针对函数执行遇到的不同错误,GetLastError的返回值是不同的。其针对Windows系统提供的API函数,执行失败获取其错误码。获取调用线程的最后错误代码值,最后一个错误代码是基于每个线程维护的,多个线程不会覆盖彼此的最后错误代码。

利用https://editor.csdn.net/md/?articleId=145371197介绍的文件删除函数进行说明。如果目标路径没有要删除的文件,则就会报错。

此时在本机的D盘下已经没有名为111.gif的文件,这里要删除D盘下的111.gif文件

cpp 复制代码
BOOL bret1 = DeleteFile(_T("D:\\111.gif"));
if (bret1)
{
	MessageBox(NULL, _T("删除成功"), _T("提示"), MB_OK);	
}
else
{
	MessageBox(NULL, _T("删除失败"), _T("提示"), MB_OK);
}

理论上来说,由于已经不存在该文件,由于程序语法正确,编译可以通过,但是该删除函数会报错。

即便我们清楚,函数执行失败的原因是没有目标文件要删除的文件,但是对于使用者来说,其不清楚为什么删除失败,那么就需要用到函数GetLastError。

下断点后运行,进入DeBug模式

可以看到错误码为2

但是根据这个错误码"2",我们并不知道具体是什么原因。在网上查询发现,错误码"2"表示找不到指定文件

实际上,这种错误码有很多,每个错误码表示的错误信息是不一样的,那么我们如何找到其对应信息?每次都上网查询很不方便。

微软为我们提供了一个工具,可以根据GetLastError返回的错误码找的其对应的错误信息。位置在vs编译器的工具->错误查找

输入2,点击查找,则显示系统找不到指定文件,与我们在网上找的结果相同

这说明由于指定路径并不存在该文件,因此系统找不到指定的文件,与我们预料的原因相同。

再试一下另一种情况,D盘下存在一个命名为111new.gif的文件,其为只读文件。

此时要删除该文件

cpp 复制代码
BOOL bret1 = DeleteFile(_T("D:\\111new.gif"));
if (bret1)
{
	MessageBox(NULL, _T("删除成功"), _T("提示"), MB_OK);
}
else
{
	DWORD dwerror = GetLastError();
	MessageBox(NULL, _T("删除失败"), _T("提示"), MB_OK);
}

此时给出的错误码为5

查找发现对应的错误信息为拒绝访问。

这是由于只读文件造成的,如果将只读去掉,则程序可以正常删除文件。

删除成功

则可将代码改为

cpp 复制代码
BOOL bret1 = DeleteFile(_T("D:\\111new.gif"));
if (bret1)
{
	MessageBox(NULL, _T("删除成功"), _T("提示"), MB_OK);
}
else
{
	DWORD dwerror = GetLastError();
	if (dwerror == 2)
	{
		MessageBox(NULL, _T("文件不在指定路径"), _T("提示"), MB_OK);
	}
	else
	{
		MessageBox(NULL, _T("删除失败"), _T("提示"), MB_OK);
	}
}

运行得到如下结果

三、使用错误码的宏

上文已经提到,错误码为2表示系统找不到指定的文件;错误码为5表示拒绝访问。但是错误码有上万个,不可能全都记住。而且错误码对应的数字随着微软系统的升级后期是有可能发生变化的,因此最好使用Windows提供给我们的错误码的宏,而不是使用数值。

利用关键字查找办法:Win32 Error Code

直接在搜索引擎中进行搜索,即可将错误码对应的错误原因列出,下面是部分错误码示例

ERROR_SUCCESS (0): 操作成功完成。

ERROR_INVALID_FUNCTION (1): 错误的函数。

ERROR_FILE_NOT_FOUND (2): 系统找不到指定的文件。

ERROR_PATH_NOT_FOUND (3): 系统找不到指定的路径。

ERROR_ACCESS_DENIED (5): 访问被拒绝。

ERROR_INVALID_HANDLE (6): 句柄无效。

ERROR_NOT_ENOUGH_MEMORY (8): 存储空间不足,无法处理此命令。

ERROR_BAD_FORMAT (11): 试图加载格式错误的程序。

ERROR_INVALID_ACCESS (12): 访问代码无效。

ERROR_INVALID_DATA (13): 数据无效。

ERROR_OUTOFMEMORY (14): 存储空间不足,无法完成此操作。

ERROR_INVALID_DRIVE (15): 系统找不到指定的驱动器。

ERROR_NO_MORE_FILES (18): 没有更多文件。

ERROR_WRITE_PROTECT (19): 介质受写入保护。

ERROR_BAD_UNIT (20): 系统无法找到指定的设备。

ERROR_NOT_READY (21): 设备未就绪。

ERROR_BAD_COMMAND (22): 设备不识别的命令。

ERROR_CRC (23): 数据错误(循环冗余检查)。

ERROR_BAD_LENGTH (24): 程序发出命令,但命令长度不正确。

ERROR_SEEK (25): 驱动器无法找到磁盘上的特定区域或磁道。

ERROR_NOT_DOS_DISK (26): 无法访问指定的磁盘或软盘。

ERROR_SECTOR_NOT_FOUND (27): 驱动器找不到请求的扇区。

ERROR_WRITE_FAULT (29): 系统无法写入指定的设备。

ERROR_READ_FAULT (30): 系统无法从指定的设备读取。

ERROR_GEN_FAILURE (31): 附加到系统的设备无法正常工作。

那么最好将程序中的错误码数字变为宏,这里将错误码2改为对应的宏即可。

cpp 复制代码
if (dwerror == ERROR_FILE_NOT_FOUND)

同时也可以看到该宏与错误码2对应

需要说明。在DeleteFile等函数调用成功后,也可以调用GetLastError,此时返回的错误码为0,即操作成功完成。

总结

Windows 程序设计6:错误码的查看。

相关推荐
Clown954 分钟前
Go语言爬虫系列教程(一) 爬虫基础入门
开发语言·爬虫·golang
南风与鱼4 分钟前
STL详解 - 红黑树模拟实现map与set
c++·红黑树封装map和set
Watermelo6176 分钟前
前端如何应对精确数字运算?用BigNumber.js解决JavaScript原生Number类型在处理大数或高精度计算时的局限性
开发语言·前端·javascript·vue.js·前端框架·vue·es6
虾球xz2 小时前
游戏引擎学习第276天:调整身体动画
c++·学习·游戏引擎
Aric_Jones2 小时前
lua入门语法,包含安装,注释,变量,循环等
java·开发语言·git·elasticsearch·junit·lua
Akiiiira2 小时前
【日撸 Java 三百行】Day 12(顺序表(二))
java·开发语言
虾球xz2 小时前
游戏引擎学习第275天:将旋转和剪切传递给渲染器
c++·学习·游戏引擎
EndingCoder2 小时前
2025年JavaScript性能优化全攻略
开发语言·javascript·性能优化
码上淘金7 小时前
【Python】Python常用控制结构详解:条件判断、遍历与循环控制
开发语言·python
Brilliant Nemo7 小时前
四、SpringMVC实战:构建高效表述层框架
开发语言·python