如何处理无效的异常处理程序例程?
Posted
技术标签:
【中文标题】如何处理无效的异常处理程序例程?【英文标题】:how can i handle an invalid exception handler routine? 【发布时间】:2020-04-13 15:13:33 【问题描述】:我正在构建一个程序,用于创建和删除目录。我使用 MSVC 编译器(Visual Studio 2017),这就是我不能分别使用“getcwd()”或“dirent.h”的原因。 我尝试了几种不同的方法来获取当前工作目录,但总是有问题。我设法用“_wgetcwd()”打印了 cwd。但是,在我的研究中,我找不到如何转换它的输出以在“_rmdir()”或“_wrmdir()”中使用它。
我的主要目标是能够删除目录而无需安装一些新的编译器。如果满足这个条件,任何帮助表示赞赏,因为我已经尝试安装不同的编译器,但我没有让它工作。我还尝试了不同的方法来获取 cwd 并将其转换为所需的数据类型,但在我的 IDE 范围和我的基本知识范围内没有任何效果。
我几乎是编程的初学者,我正在学习这本书,不幸的是使用了“dirent.h”。以下是我当前代码的 sn-p,其中我已经消除了所有错误。但是我仍然得到最后一个烦人的异常:
#include <iostream>
#include <stdlib.h>
#include<string>
#include <direct.h>
int main()
int t = 0;
std::string str;
char xy = ' ';
char* _DstBuf = &xy;
const char* uniquename;
uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);
std::cout << "Current path is ";
while (*uniquename != '\0') // this pointer points to the beginning of my path
std::cout << char(*uniquename); // prints one char of the path name for each iteration
char var = char(*uniquename);
str.push_back(var); //here the exception below is thrown.
// jump to the next block of memory
uniquename++;
std::cout << str <<'\n';
const char* lastchance = str.c_str();
if (_wchdir('..'))
std::cout << "changing directory failed.\n";
if (_rmdir(lastchance) == -1 && errno == ENOTEMPTY)
std::cout << "Given path is not a directory, the directory is not empty, or the directory is either the current working directory or the root directory.\n";
else if (_rmdir(lastchance) == -1 && errno == ENOENT)
std::cout << "Path is invalid.\n";
else if (_rmdir(lastchance) == -1 && errno == EACCES)
std::cout << "A program has an open handle to the directory.\n";
else if (_rmdir(lastchance))
std::cout << "removing directory still not possible\n";
这是我得到的例外: Experimentfile.exe 中 0x6E656D69 处未处理的异常:0xC00001A5:检测到无效的异常处理程序例程(参数:0x00000003)。
【问题讨论】:
您是如何得出结论的,即getcwd()
对您来说超出了范围,使用那个编译器?这似乎不太可能。
哪一行导致异常,在什么情况下?
uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);
正在尝试将 CWD 的名称加载到单个字符变量 xy
中。见:char* _DstBuf = &xy;
您对_getdcwd
的参数不正确。您正在传递一个指向单个字符的指针,但告诉该函数它可以在那里存储多达 260 个字符。一旦你完成了所有的赌注,接下来会发生什么。您可以将 NULL 作为缓冲区参数传递,让它为您分配内存,或者将您分配的适当大小的数组或内存块的地址传递给它。
@nicomp:代码示例中有一个注释在哪里,抛出了异常。
【参考方案1】:
因此,如果您打算以 C 风格进行编程(即使您有 C++ 编译器),您也必须了解数组和指针的工作原理。这是一个远太大的话题,无法从互联网上学习,您需要good book。
但是我会指出一些错误
char xy = ' ';
char* _DstBuf = &xy;
const char* uniquename;
uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);
这完全是错误的。它可以编译,但这并不意味着它会起作用。这是需要的
char DstBuf[_MAX_PATH];
_getdcwd(0, DstBuf, _MAX_PATH);
_getdcwd 需要一个作为指针传递的 array(请参阅,您需要了解数组和指针)。
然后您尝试打印出结果并将结果分配给字符串。同样,代码比它需要的复杂得多。这是更简单的版本
std::string str = DstBuf;
std::cout << str <<'\n';
然后您尝试更改目录。我不知道你为什么使用宽版本 _wchdir
当你有窄字符串时,改用 _chdir
。再次参数不正确,'..'
是一个多字符文字,但_chdir
需要一个 C 字符串。这是使用_chdir
的正确版本。
if (_chdir(".."))
std::cout << "changing directory failed.\n";
然后你尝试删除一个目录四次,显然你不能多次删除一个目录。
等等,等等。
【讨论】:
【参考方案2】:您的代码存在几个问题。我认为你的异常是由这一行引起的:
uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);
调用_getdcwd
并将一个指向单个字符的指针传递给它,同时还指定该指针最多可以容纳_MAX_PATH
。这是完全未定义的行为。
要解决这个问题,我认为你应该彻底改变你正在做的事情。除了像 std::string
这样分散的 C++ 部分之外,您的代码读起来像 C 代码。从 C++17 开始,标准库支持内置文件系统操作。因此,您可以使用 std::filesystem
以更简洁和安全的方式重写代码。
... // get path to delete and store it in del_path (del_path should be an std::filesystem::path object)
std::filesystem::remove_directories(del_path); // Recursive delete the directory specified by del_path
...
注意:如果失败,std::filesystem::remove_directories
将抛出 std::filesystem::filesystem_error
。
您可以使用std::filesystem
到std::filesystem::current_path
获取当前目录。
我还建议在 C++ 上选择 better book,因为这似乎并没有教你好的做法
【讨论】:
非常感谢! 文件系统让它变得如此简单!以上是关于如何处理无效的异常处理程序例程?的主要内容,如果未能解决你的问题,请参考以下文章