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
.
为什么会这样?
这是 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,依此类推。
这应该很容易理解。如果您的实现支持argv
type wchar_t**
,那么它将以实现定义的方式在您的实现上工作。如果您需要可移植性,请不要依赖任何实现定义的内容。
此外,wcslen()
被声明为返回一个size_t
值,您应该将其与%zu
指令一起使用来打印,并且#include <wchar.h>
.
我认为这些都不会导致您的问题,但它们都会导致未定义的行为。
main
需要类型为int
and的参数char**
(或char*[]
等价的)。还有一个可选的第三个参数,即环境字符串数组。
但是发生的情况是,大多数编译器都对main
. 它很高兴地让您声明main
为 argc 和 argv 采用任何类型的参数(或不使用参数)。我认为这在很大程度上是历史性的,具有向后兼容性C
。并且由于将类型隐式转换为char*[]
,wchar_t*[]
字符串会以完全不同的方式进行解释。
因此,正确地说您从 wcslen 获得了预期的 +1 是不正确的。这是技术上未定义的行为。
两个可能的修复:
简单的解决方法就是将第二个参数改为字符串数组char
而不是wchar_t
字符串。
int main(int argc, char* argv[])
如果您的编译器是 Visual Studio 并且您希望传递 Unicode 参数,则解决方法是将程序的入口点声明wmain
为main
int wmain(int argc, wchar_t* argv[])
上面的wmain
修复肯定会用mingw编译,但我不确定链接器是否支持启用wmain
作为程序入口点。试一试就知道了。