main()std :: string而不是char **为什么要排除

时间:2013-06-30 19:02:25

标签: c++

编译器发出警告 warning: second argument of ‘int main(int, std::string*)’ should be ‘char **’ [-Wmain]

当我选择加入时

int main(int argv, std::string a[])

而不是

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

如果你能提出一个理由,也可以告诉dotell字符串方法有什么问题。

我的意思是std :: string是字符表示/字符串表示的后代,对于C ++,为什么要烦扰C风格?

同时

在标准实施方面真的没有黑客吗?

3 个答案:

答案 0 :(得分:10)

原因很简单:语言规则不强制您的表单,您使用的实现不会通过自己的选择支持它。

引用标准3.6.1p2

  

实现不应预定义主函数。此功能不应过载。它应该具有int类型的返回类型,否则其类型是实现定义的。所有实现都应允许以下两个主要定义:

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

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

在后一种形式中,argc应该是从运行程序的环境传递给程序的参数数量。如果argc非零,则这些参数应在argv [0]到argv [argc-1]中提供,因为指向以null结尾的多字节字符串(NTMBS)(17.3.2.1.3.2)和argv [0]的初始字符的指针应为指向NTMBS的初始字符的指针,该NTMBS表示用于调用程序或“”的名称。 argc的值应为非负值。 argv [argc]的值应为0. [注意:建议在argv之后添加任何其他(可选)参数。 ]

编辑:以涵盖其他问题:

没有必要“破解”任何东西,因为没有必要停止使用一个函数或类来获取原始的argc和argv并将其处理为矢量字面意思,或者更好地解析它并将处理后的数据映射到内部变量。我们有很多漂浮在那里的人,每年创造超过少数main()的人可能已经使用过他们中的一个或者他们自己的。

答案 1 :(得分:8)

解决方法:

 vector<string> args(argv, argv + argc);

 for (auto s: args) 
      cout << s << endl;

std::stringstd::vector是重量级的对象。在构造期间使用动态内存分配。

第二种方法是使用my RO library。下面的代码将在argv数组周围创建轻量级迭代器范围对象:

 auto args = ro::range(argv,argv+argc);

 for (auto s: args) 
      cout << s << endl;

答案 2 :(得分:1)

您已被告知实施需要不支持它的原因。但是,您的实现也不会希望支持它:

调用main的(通常是预编译的)代码传递intchar**(在某些实现中作为扩展名传递char**;实际上,在许多平台上它准确地获取操作系统已经提供的数据并将其传递给它。很容易支持忽略尾随参数(通常它们以相反的顺序被推送到堆栈,所以忽略其他参数只意味着不访问它们,不需要额外的逻辑)。但是,您不能只将char**读出为std::string*,因此编译器必须生成额外的代码来支持此接口。鉴于任何使用该接口的源代码都是不可移植的,很少有人会使用它,并且考虑到原始接口工作正常,实现该替代接口只会浪费资源。