0

argv[1]似乎比输入的内容多返回 1 个字符。 argv[2]是正确的。

#include <stdio.h>
int main(int argc, wchar_t *argv[])
{
  printf("%d %d\n",wcslen(argv[1]),wcslen(argv[2]) );
  return 0;
}

我正在使用 mingw32 进行编译。我用gcc myprog.c.

为什么会这样?

4

2 回答 2

1

这是 C 标准草案 n1570.pdf 的引述:

5.1.2.2.1 程序启动

1程序启动时调用的函数名为main。实现没有声明这个函数的原型。它应定义为返回类型为 int 且不带参数:

int main(void) { /* ... */ }

或者带有两个参数(这里称为 argc 和 argv,尽管可以使用任何名称,因为它们是声明它们的函数的局部变量):

int main(int argc, char *argv[]) { /* ... */ }

或同等学历; 10)或以其他一些实现定义的方式。

10) 因此,int 可以替换为定义为 int 的 typedef 名称,或者 argv 的类型可以写为 char ** argv,依此类推。

这应该很容易理解。如果您的实现支持argvtype wchar_t**,那么它将以实现定义的方式在您的实现上工作。如果您需要可移植性,请不要依赖任何实现定义的内容。

此外,wcslen()被声明为返回一个size_t值,您应该将其与%zu指令一起使用来打印,并且#include <wchar.h>.

我认为这些都不会导致您的问题,但它们都会导致未定义的行为。

于 2013-01-19T04:20:44.873 回答
1

main需要类型为intand的参数char**(或char*[]等价的)。还有一个可选的第三个参数,即环境字符串数组。

但是发生的情况是,大多数编译器都对main. 它很高兴地让您声明main为 argc 和 argv 采用任何类型的参数(或不使用参数)。我认为这在很大程度上是历史性的,具有向后兼容性C。并且由于将类型隐式转换为char*[]wchar_t*[]字符串会以完全不同的方式进行解释。

因此,正确地说您从 wcslen 获得了预期的 +1 是不正确的。这是技术上未定义的行为。

两个可能的修复:

简单的解决方法就是将第二个参数改为字符串数组char而不是wchar_t字符串。

int main(int argc, char* argv[])

如果您的编译器是 Visual Studio 并且您希望传递 Unicode 参数,则解决方法是将程序的入口点声明wmainmain

int wmain(int argc, wchar_t* argv[])

上面的wmain修复肯定会用mingw编译,但我不确定链接器是否支持启用wmain作为程序入口点。试一试就知道了。

于 2021-08-12T00:37:26.613 回答