标准做法是用来argv
访问命令行参数。您可能会发现在某些架构上还有其他方法可以做到这一点,但它们不太可能是可移植的,而且这里似乎没有太多理由不采用标准做法。要将值读入 int,您可以使用strtol
long n = strtol( argv[1], NULL, 0 );
(请注意,我倾向于使用strtol
to,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;
}