【问题标题】:Defining own main functions arguments argc and argv定义自己的主函数参数 argc 和 argv
【发布时间】:2010-12-03 22:37:01
【问题描述】:

我想创建一个 QApplication 类型的对象,它需要主函数参数 argc 和 argv 作为输入:

QApplication app(argc, argv);

因为我在一个用户定义的函数中而无法访问主函数,所以我想自己定义这个参数。我尝试了几种方法,但我无法正确进行类型转换。我的最后一种方法也不起作用:

int argc = 1;
char **argv; 
char arguments[1][12] = {{"cgalExample"}};
argv = arguments;

感谢任何提示。

【问题讨论】:

  • 能否请您澄清什么不起作用?没有编译?执行错误?没有达到你的预期?
  • Visual Studio 2008 下的编译器错误:无法转换类型。 gs 的提示效果很好。

标签: c++ qt


【解决方案1】:

如果你想疯狂地垂头丧气,那么你想要像下面这样的东西。关键是argv不是constargvNULL终止,argcargv中可用元素的个数包括程序名。它必须是可修改的,因此您不能使用字符串文字 - argv[i] 需要指向可修改的字符数组。

int my_main() {
    char  arg0[] = "programName";
    char  arg1[] = "arg";
    char  arg2[] = "another arg";
    char* argv[] = { &arg0[0], &arg1[0], &arg2[0], NULL };
    int   argc   = (int)(sizeof(argv) / sizeof(argv[0])) - 1;

    QApplication the_application(argc, &argv[0]);
    return the_application.run();
}

该标准(ISO/IEC 9899:1999 第 5.1.2.2.1 节)声明以下关于托管环境中的 argcargv 是正确的:

  • argc 的值应为非负数。
  • argv[argc] 应为空指针。
  • 如果 argc 的值大于零,则数组成员 argv[0]argv[argc-1] 应包含指针到字符串,在程序从宿主环境中的其他地方启动之前,宿主环境会给出实现定义的值。如果宿主环境不能提供包含大写和小写字母的字符串,则实现应确保以小写形式接收字符串。
  • 如果argc的值大于零,则argv[0]所指向的字符串代表程序名argv[0][0] 如果程序名称在主机环境中不可用,则应为空字符。如果argc的值大于1,则argv[0]argv[argc-1]所指向的字符串代表程序参数
  • argcargv参数以及argv数组所指向的字符串都可以被程序修改,并在程序启动和程序终止之间保留它们最后存储的值。

QApplication 声明如下:

警告:argcargv 引用的数据必须在 QApplication 的整个生命周期 目的。此外,argc 必须是 大于零且argv 必须 至少包含一个有效字符 字符串。

注意:argcargv 可能会更改 由于 Qt 删除了命令行参数 它可以识别。

【讨论】:

  • 只有一个问题,不应该是(int)((sizeof ...) - 1)吗?否则 argc[argv] 将指向 NULL 之后的一个...
  • @gimpf:我自己也注意到了。谢谢。
  • @alex tingle:看看 C99 第 6.7.8 节的第 14 条或 C++98 中第 8.5.2 节的第 1 条。两者都清楚地表明 a char 数组可以从字符串文字初始化(可选地用大括号括起来);字符串文字的连续字符初始化数组的成员。
  • &arg0[0]arg0 不一样吗?
  • @gs:在大多数情况下都是如此。如果存在这样的特化,C++ 将选择像 template <typename T, size_t N> void foo(T (&ary)[N]) 这样的模板特化而不是 template <typename T> void foo(T val)。如果arg0 匹配char (&)[12] 之前的类型将降级为char*。我刚刚养成了传递 char* 或显式引用数组的习惯。
【解决方案2】:

又快又脏,但为QApplication工作:

char *argv[] = {"program name", "arg1", "arg2", NULL};
int argc = sizeof(argv) / sizeof(char*) - 1;

如需更完整且符合 C 标准的解决方案,请参阅 D.Shawley's answer

为什么您的解决方案不起作用很简单:

array[i][j] 产生i*j 矩阵。但你真正想要的是一个数组,里面有指向字符串的指针。

【讨论】:

  • 非常感谢。这个是在 VS 2008 下编译的。
  • 可能要提一下,第一个参数是程序名。
  • 对程序名称和 NULL 进行了很好的更正,但 char* 仍应指向可变字符串......文字字符串不是。
  • 如果 argv[argc] != NULL;代码应该能够依赖它。
【解决方案3】:

尽管 C 和 C++ 标准都不需要它,但大多数编译器都会将 main 的参数作为 _argv 和 _argc 提供给您。如果内存服务于 POSIX,则需要这样做。无论如何,你需要使用类似的东西:

extern int _argc;
extern char *_argv[];

然后你就可以像平常一样使用它们了。

【讨论】:

    【解决方案4】:

    你为什么要关心 argv 中文本的大小,我会让编译器来做:

    int argc = 1;
    char* argv[] = {"Hello Qt!"}; // exactly as it is defined in main
    

    【讨论】:

    • 好吧,这并不能编译为一件事:“错误:用于初始化'char *'的大括号初始化程序”
    • @alex 它对我来说编译得很好(VC2008)。你用的是什么编译器?
    • 是的,但不是要求 argv 数组本身以空值结尾吗?
    • @gimpf,这是一个完全不同的问题。 execl 函数采用以空值结尾的参数。 argv 本身不是空终止的。
    • @gs:标准要求argvNULL 终止的。具体内容见我的回答。
    【解决方案5】:

    我希望这可行:

    char* argv[1];
    argv[0] = "cgalExample";
    

    【讨论】:

    • 您正在使用 const char[] 初始化 char*。淘气!
    【解决方案6】:

    怎么样...

    int argc = 2;
    const char* argv[] ={"program","first-argument"}; 
    

    ...或者如果您需要它们是非常量...

    int argc = 2;
    char* argv[] ={strdup("program"),strdup("first-argument")}; 
    

    【讨论】:

    • 如果你用过这个,别忘了打电话给free(ptr)
    猜你喜欢
    • 2011-12-17
    • 2020-01-23
    • 1970-01-01
    • 2015-09-01
    • 2013-09-08
    • 2016-08-25
    • 2018-12-01
    • 2021-07-01
    • 1970-01-01
    相关资源
    最近更新 更多