Command line 正确处理std.getopt.GetOptException

Command line 正确处理std.getopt.GetOptException,command-line,command-line-arguments,d,Command Line,Command Line Arguments,D,当缺少必需的命令行参数时,如何正确处理引发的std.getopt.GetOptException异常 声明需要的参数会引发以下错误,该错误太过冗长: std.getopt.GetOptException@/Library/D/dmd/src/phobos/std/getopt.d(755): Required option file|f was not supplied ---------------- /Library/D/dmd/src/phobos/std/format.d-mixin-1

当缺少必需的命令行参数时,如何正确处理引发的
std.getopt.GetOptException
异常

声明需要的参数会引发以下错误,该错误太过冗长:

std.getopt.GetOptException@/Library/D/dmd/src/phobos/std/getopt.d(755): Required option file|f was not supplied
----------------
/Library/D/dmd/src/phobos/std/format.d-mixin-1127:1138 @safe std.getopt.GetoptResult std.getopt.getopt!(std.getopt.config, immutable(char)[], immutable(char)[], immutable(char)[]*, std.getopt.config, immutable(char)[], immutable(char)[], immutable(char)[]*, immutable(char)[], immutable(char)[], bool*, immutable(char)[], immutable(char)[], bool*).getopt(ref immutable(char)[][], std.getopt.config, immutable(char)[], immutable(char)[], immutable(char)[]*, std.getopt.config, immutable(char)[], immutable(char)[], immutable(char)[]*, immutable(char)[], immutable(char)[], bool*, immutable(char)[], immutable(char)[], bool*) [0xbb5a9d1]
source/app.d:11 _Dmain [0xbb58996]
std.getopt.GetOptException@/Library/D/dmd/src/phobos/std/getopt.d(755): Required option key|k was not supplied
使用以下代码复制它:

import std.stdio;
import std.getopt;

int main(string[] args)
{
    string key;
    string inputFile;
    bool encrypt;
    bool decrypt;

    auto result = getopt(
        args,
        std.getopt.config.required,
        "key|k", "The key to use", &key,
        std.getopt.config.required,
        "file|f", "The file to encrypt/decrypt", &inputFile,
        "encrypt|e", "Encrypt the file", &encrypt,
        "decrypt|d", "Decrypt the file", &decrypt
    );

    if (result.helpWanted) {
        defaultGetoptPrinter("Some information about the program.", result.options);
    }

    return 0;
}

一种合理的方法是将
getopt
调用包装在
try-catch
块中,捕获任何错误,并在退出之前只写入错误消息部分。这将避免写入堆栈跟踪,这对大多数用户都没有帮助。修改上述示例:

import std.stdio;
import std.getopt;

int main(string[] args)
{
    string key;
    string inputFile;
    bool encrypt;
    bool decrypt;

    try {
        auto result = getopt(
            args,
            std.getopt.config.required,
            "key|k", "The key to use", &key,
            std.getopt.config.required,
            "file|f", "The file to encrypt/decrypt", &inputFile,
            "encrypt|e", "Encrypt the file", &encrypt,
            "decrypt|d", "Decrypt the file", &decrypt
        );

        if (result.helpWanted) {
            defaultGetoptPrinter("Some information about the program.", result.options);
        }
    }
    catch (Exception e) {
        stderr.writefln("Error processing command line arguments: %s", e.msg);
        return 1;
    }

    return 0;
}
运行时出现错误消息:

Error processing command line arguments: Required option file|f was not supplied

D语言“学习”论坛上有一条与此相关的线索可能很有用:。我已经编写了一些开源命令行工具,这些工具的示例更为广泛,例如:

一种合理的方法是将
getopt
调用包装在
try catch
块中,捕获任何错误,并在退出之前只写入错误消息部分。这将避免写入堆栈跟踪,这对大多数用户都没有帮助。修改上述示例:

import std.stdio;
import std.getopt;

int main(string[] args)
{
    string key;
    string inputFile;
    bool encrypt;
    bool decrypt;

    try {
        auto result = getopt(
            args,
            std.getopt.config.required,
            "key|k", "The key to use", &key,
            std.getopt.config.required,
            "file|f", "The file to encrypt/decrypt", &inputFile,
            "encrypt|e", "Encrypt the file", &encrypt,
            "decrypt|d", "Decrypt the file", &decrypt
        );

        if (result.helpWanted) {
            defaultGetoptPrinter("Some information about the program.", result.options);
        }
    }
    catch (Exception e) {
        stderr.writefln("Error processing command line arguments: %s", e.msg);
        return 1;
    }

    return 0;
}
运行时出现错误消息:

Error processing command line arguments: Required option file|f was not supplied

D语言“学习”论坛上有一条与此相关的线索可能很有用:。我已经编写了一些开源命令行工具,这些工具的示例更为广泛,例如…

感谢您的回复。使用try-catch块显然可以防止将错误打印到stdout,但是这种方法也可以防止将defaultsGetoptPrinter生成的帮助文本打印到stdout。不可能同时拥有try-catch块和帮助消息吗?要获取帮助字符串,必须调用getopt,以便正确解析所有参数。这意味着在catch try块中对它进行第二次调用,但参数保证成功。组织代码执行此操作的一种方法是创建一个调用getopt的包装器函数。对于命令行参数和从catch子句生成帮助字符串,都可以使用它。在我引用的论坛帖子中有一个例子正好说明了这一点。请注意,将
--help
作为参数字符串传递可以避免关于所需参数的错误。感谢您的回复。使用try-catch块显然可以防止将错误打印到stdout,但是这种方法也可以防止将defaultsGetoptPrinter生成的帮助文本打印到stdout。不可能同时拥有try-catch块和帮助消息吗?要获取帮助字符串,必须调用getopt,以便正确解析所有参数。这意味着在catch try块中对它进行第二次调用,但参数保证成功。组织代码执行此操作的一种方法是创建一个调用getopt的包装器函数。对于命令行参数和从catch子句生成帮助字符串,都可以使用它。在我引用的论坛帖子中有一个例子正好说明了这一点。请注意,将
--help
作为参数字符串传递可以避免关于所需参数的错误。