【问题标题】:argc never has a value above 2 [closed]argc 的值永远不会超过 2 [关闭]
【发布时间】:2014-03-24 23:26:35
【问题描述】:

如果我在 Visual Studio 2013 下编译这段代码

int main(int argc, char* argv[])
{
std::cout << "arg count: "<< argc << "/n";
}

然后在没有附加参数的情况下运行它(即>program.exe),它会输出

arg count: 1

输出 1 个参数 (>program.exe arg1)

arg count: 2

但这就是奇怪的地方。如果我输入 (>program.exe arg1 arg2) 它输出

arg count: 2

“arg count”应该是3,不是吗?

使用 (>program.exe arg1 arg2 arg3) 输出

arg count: 2

在这种情况下应该是 4...

打印 argv[3] 出于某种原因可以正常工作。

为什么会这样?

【问题讨论】:

  • 当您摆脱打印argv[3] 的尝试时会发生什么?这会在您的程序中引入未定义的行为。
  • 你能说明你是如何提供这些论点的吗?具体来说,你是如何调用程序的?
  • argv 的最后一个指针通常初始化为NULL,这样就可以在没有索引的情况下迭代参数。
  • 请注意,此处使用的标准 C/C++ 类型是 'char' 而不是 'CHAR'。
  • @tomatopipps 此代码应该可以正常工作。要么你自己搞砸了论点,要么你的构建被破坏了。您是否尝试过重新启动计算机? ;-)

标签: c++ argc


【解决方案1】:

C++ 标准的3.6.1 部分定义了main 及其参数的工作方式:

在后一种形式中,为了便于说明,第一个函数参数是 称为 argc,第二个函数参数称为 argv,其中 argc 应为参数的数量 从程序运行的环境传递给程序。如果 argc 不为零,则这些参数 应在 argv[0]argv[argc-1] 中提供,作为指向以空字符结尾的初始字符的指针 多字节字符串 (ntmbs s) (17.5.2.1.4.2) 和 argv[0] 应该是指向 ntmbs 表示用于调用程序的名称或“”。 argc 的值应为非负数。 argv[argc]的值为0。 [注意:建议任何进一步的(可选)参数是 在 argv 之后添加。 ——尾注]

这意味着使用符合标准的编译器,您应该能够访问argv[argc]。 但是,使用 n > argc 访问 argv[n] 是未定义的。它可能会崩溃,但不是必须的。

您遇到的情况很奇怪,因为显然这些参数是作为单个参数处理的。如果您完全按照说明提供参数,则不会发生这种情况。

您应该修复main 的签名。标准至少保证这两个签名,其他的都是实现定义的:

— () 返回 int 和

的函数

——(int,pointer to pointer to char)返回int的函数

当您想要访问参数时,适当的签名是int main(int argc, char** argv)

【讨论】:

  • 我的问题是 argc 没有反映参数数量的价值,我将问题编辑得更简洁。
  • 在函数参数的上下文中,char **argv 等价于char *argv[]
  • @AmbrozBizjak 旧版本的问题有CHAR 作为类型,这显然是错误的(除非它是char 的typedef)。我指的是那个。
  • “这很可能是一个编译器错误。” – 事实上,这很可能不是编译器错误,而是使用错误。几乎可以肯定地排除这种基本功能的编译器错误。其他所有解释,包括 OP 完全是错误的,都更有可能。
  • @KonradRudolph 在我读到 VS2013 之前,我一直在怀疑一个古老的不符合标准的编译器。你是对的,这可能不是真的 => 已删除。
【解决方案2】:

我猜你要么输入为

(>program.exe "arg1 arg2"

(>program.exe arg1,arg2

【讨论】:

    【解决方案3】:

    好的,事实证明,问题出在我未在此处包含的某些代码中。我的代码是:

    if (argc = 2) { do some stuff }
    

    应该是的

    if (argc == 2) { do some stuff }
    

    我觉得自己很愚蠢:\

    【讨论】:

    • 启用警告,这样的错误不会再发生。不过我不知道 VS2013 的标志。
    • 警告级别 4。在解决方案资源管理器中右键单击项目,选择属性,在左侧的树中单击 C/C++,找到警告级别并将其下拉更改为级别 4。不要全选,大多数库不能在 All 级别上保持干净。
    • @Kate VC++ 是否有一个特殊的编译器标志来包含库的包含文件并忽略它们的警告? GCC/clang 有 -isystem 。这样我就可以编译我自己的具有最高警告级别的代码。没有它我会发疯的。
    • 我希望,但我不这么认为@KonradRudolph
    猜你喜欢
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多