标准做法是使用argv
来访问命令行参数。您可能会发现在某些体系结构中还有其他方法可以做到这一点,但它们不太可能是可移植的,在这里似乎没有太多理由不遵循标准惯例。要读取值到一个int您可以使用strtol
long n = strtol(argv[1], NULL, 0);
(请注意,我倾向于使用strtol
因为你已经在投入多一点控制和错误处理更喜欢atoi
- 但不是很多)
您也可以使用流如下:
istringstream ss(argv[1]);
long n;
ss >> n;
两个事情并关心我你正在试图做什么,虽然:首先你想要的变量值,设置在运行时函数被封装。从逻辑上讲,这会使你的代码不易维护,因为你的函数和一个外部影响(一个命令行参数)之间会有一个不可见的依赖关系 - 所以你的函数的确定性属性会受到影响。实际上,这会让测试你的功能变得更加困难 - 尤其是使用自动化单元测试,因为在运行之前,没有办法设置该值。其次,如果要复合这一点,您正在寻求将a
变量的范围限制为未命名名称空间内的编译单元。这有两个不良影响。首先,没有任何测试工具或任何其他代码能够从自动UT的角度再次看到这个变量,这是非常糟糕的。其次,a
在您的编译单元中成为有效的“全局”。在这个编译单元的函数中,使用a
的方式和时间会非常棘手,这对维护你的代码的任何人来说都有点头痛。我会假设你没有使用多线程,这真的会导致问题。
我想知道为什么你不想通过argv[1]
到print_from_external_file()
的原因,但我真的认为这是最好的事情。如果你不觉得你可以直接通过这个变量作为字符串或转换为int,你可以考虑创建可能在传递一个命令行参数或配置对象:
configuration c(argc, argv); // This contains the hard work of parsing the CL
print_from_external_file(c);
这隐藏了大部分的解析命令行的努力工作。更好的是它可以让你给CL参数增加真正的含义。比方说,在a
变量表示目录号,您configuration
类的构造函数可以简单地这样做:
configuration::configuration(int argc, char* argv[])
{
// ...
catalogNo_ = strtol(argv[1], NULL, 0);
,然后如果访问添加:
int configuration::get_catalog_no() const { return catalogNo_; }
则变得更加明显在print_from_external_file()
我们在做什么:
void print_from_external_file(const configuration& c)
{
cout << c.get_catalog_no() << endl;
}
这是假设a被定义在与main相同的范围。在我的MWE中情况并非如此。 – BillyJean