简体   繁体   English

如何处理无效的异常处理程序例程?

[英]how can i handle an invalid exception handler routine?

I'm building a program, that creates and deletes directories.我正在构建一个程序,它创建和删除目录。 I use the MSVC compiler (Visual Studio 2017), which is the reason i can't use "getcwd()" or "dirent.h" respectively.我使用 MSVC 编译器(Visual Studio 2017),这就是我不能分别使用“getcwd()”或“dirent.h”的原因。 I have tried several different ways to get the current working directory, but there was always a problem.我尝试了几种不同的方法来获取当前的工作目录,但总是有问题。 I managed to print the cwd with "_wgetcwd()".我设法用“_wgetcwd()”打印了 cwd。 However I couldn't find how I could convert it's output to use it in "_rmdir()" or "_wrmdir()" in my research.但是,在我的研究中,我找不到如何将其转换为 output 以在“_rmdir()”或“_wrmdir()”中使用它。

My main goal is to be able to remove a directory without having to install some new compiler.我的主要目标是能够删除目录而无需安装一些新的编译器。 If this condition is met, any help is appreciated, because I already tried to install a different Compiler, but I didn't got it to work.如果满足这个条件,任何帮助表示赞赏,因为我已经尝试安装不同的编译器,但我没有让它工作。 I also tried different ways to get the cwd and convert it into the desired datatype, but nothing worked with the scope of my IDE and my very basic knowledge.我还尝试了不同的方法来获取 cwd 并将其转换为所需的数据类型,但我的 IDE 的 scope 和我的基本知识都没有任何效果。

I'm pretty much a beginner in programming and I'm learning with this book, that unfortunately uses "dirent.h".我几乎是编程的初学者,我正在学习这本书,不幸的是使用了“dirent.h”。 The following is a snippet of my current code, where I have eradicated all errors.以下是我当前代码的片段,其中我已经消除了所有错误。 However I still get this last annoying exception:但是我仍然得到最后一个烦人的异常:

#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";
    }

} }

This is the exception I get: Unhandled exception at 0x6E656D69 in Experimentfile.exe: 0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000003).这是我得到的异常: Experimentfile.exe 中 0x6E656D69 处的未处理异常:0xC00001A5:检测到无效异常处理程序例程(参数:0x00000003)。

So if you are going to program in a C style (even though you have a C++ compiler) you're going to have to learn how arrays and pointers work.因此,如果您要以 C 样式进行编程(即使您有 C++ 编译器),您将必须了解 arrays 和指针是如何工作的。 It's far too big a topic to learn from the internet you need a good book .从互联网上学习的话题太大了,您需要一本好书

However I'll point out some of the errors但是我会指出一些错误

char xy = ' ';
char* _DstBuf = &xy;
const char* uniquename;
uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);

This is just hopelessly wrong.这简直是大错特错。 It compiles but that doesn't mean it's going to work.它可以编译,但这并不意味着它会起作用。 This is what's required这是需要的

char DstBuf[_MAX_PATH];
_getdcwd(0, DstBuf, _MAX_PATH);

_getdcwd requires an array which is passed as a pointer (see, you need to learn about arrays and pointers). _getdcwd 需要一个作为指针传递的数组(请参阅,您需要了解 arrays 和指针)。

Then you attempt to print out the result and assign the result to a string.然后您尝试打印出结果并将结果分配给一个字符串。 Again the code is way more complex than it needs to be.同样,代码比它需要的复杂得多。 Here's the simpler version这是更简单的版本

std::string str = DstBuf;
std::cout << str <<'\n';

Then you attempt to change directories.然后您尝试更改目录。 I don't know why you are using the wide version _wchdir when you have narrow strings, use _chdir instead.我不知道为什么当您有窄字符串时使用宽版本_wchdir ,请改用_chdir And again the parameter is incorrect, '..' is a multi character literal, but _chdir requires a C-string.再次参数不正确, '..'是一个多字符文字,但_chdir需要一个 C 字符串。 Here's the correct verison using _chdir .这是使用_chdir的正确版本。

if (_chdir("..")) {
    std::cout << "changing directory failed.\n";
} 

Then you try to remove a directory four times, obviously you can't remove a directory more than once.然后你尝试删除一个目录四次,显然你不能多次删除一个目录。

And so on, and so on.等等等等。

There are several problems with your code.您的代码有几个问题。 I think your exception is caused by this line:认为您的异常是由这一行引起的:

uniquename = _getdcwd(0, _DstBuf, _MAX_PATH);

Which is calling _getdcwd and passing it a pointer to a single character, while also specifying that the pointer can hold up to _MAX_PATH .它正在调用_getdcwd并将其传递给单个字符的指针,同时还指定该指针最多可以容纳_MAX_PATH This is completely undefined behaviour.这是完全未定义的行为。

To fix this issue I think you should completely change what you are doing.要解决这个问题,我认为你应该完全改变你正在做的事情。 Your code reads like C code, apart from the scattered C++ parts like std::string .您的代码读起来像 C 代码,除了像std::string这样分散的 C++ 部分。 Since C++17 the standard library has support for filesystem manipulation built in. Therefore you can rewrite your code using std::filesystem in a much more concise and safe way.由于 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
...

Note: std::filesystem::remove_directories will throw an std::filesystem::filesystem_error if it fails.注意:如果std::filesystem::remove_directories失败,它将抛出一个std::filesystem::filesystem_error

You can obtain the current directory using std::filesystem through std::filesystem::current_path .您可以通过std::filesystem::current_path使用std::filesystem获取当前目录。

I also recommend picking up a better book on C++ since this one does not seem to be teaching you good practices我还建议选择一本关于 C++ 的更好的书,因为这本书似乎没有教你好的做法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM