我遇到命令行参数问题。我完成了程序,所以我可以从命令行启动它:
program.exe test.txt copy_test.txt
基本上,我的程序执行以下操作:
但是(总是这样但是?!),我应该从命令行启动程序,如下所示:
program.exe -input=test.txt -output=copy_test.txt
我不知道该怎么做。我研究过,但我找不到任何帮助:(
请回复。
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
int main ( int argc, char* argv[])
{
ifstream in(argv[1]);
ofstream out(argv[2]);
vector <string> sV;
string line;
while (in >> line)
sV.push_back(line);
for ( int i = 0; i < sV.size(); i++)
sort ( sV.begin(), sV.end () );
for ( int i = 0; i < sV.size(); i++)
out << sV[i] << endl;
cin.get();
return 0;
}
答案 0 :(得分:7)
您应该解析main
个argv
个参数,以检查它们是否以-input
,-output
等开头。
从头开始这是一个地狱,但幸运的是有很多有用的库可以做到这一点,比如boost.program_options
答案 1 :(得分:0)
您可以不必让高级用户每次运行程序时都必须输入不必要的文本,而是提供显示用法的-help开关。
这通常是大多数命令行程序采用的方法,也是许多命令行爱好者欣赏命令行的简单性和强大功能的原因。
另一种选择是提供两种方法,因为一些用户可能更喜欢更长的方法。
答案 2 :(得分:0)
好吧,使用新的格式参数,您不能只是按原样将它们传递给流构造函数。
您必须检查它们是否以特定字符串开头,例如使用strncmp
,然后为输入类型传递相关位的地址,例如argv[1]+8
。
由于您提供--input=
类型前缀,您可能还希望处理它们可能处于其他顺序的可能性。
例如,您可以替换:
int main (int argc, char* argv[]) {
ifstream in(argv[1]);
ofstream out(argv[2]);
有类似的东西:
int main (int argc, char* argv[]) {
char *infile = 0;
char *outfile = 0;
for (int i = 1; i < argc; i++) {
if (strncmp (argv[i], "--input=", 8) == 0) {
infile = argv[i] + 8;
} else {
if (strncmp (argv[i], "--output=", 9) == 0) {
outfile = argv[i] + 9;
} else {
std::cerr << "Invalid argument [" << argv[i] << "]" << std::endl;
return -1;
}
}
}
if ((infile == 0) || (outfile == 0)) {
std::cerr << "Need to specify input and output file" << std::endl;
return -1;
}
ifstream in(infile);
ofstream out(outfile);
答案 3 :(得分:0)
我有点迟到了,但我会提供更新的答案。您可以使用'getopt'实际获得C ++中所需的功能。使用getopt_long()
,您可以创建单个字符选项(如-c
)或命名选项(如--input
)。您还可以使用getopt_long_only()
,这样您只需使用一个短划线即可传递命名选项。例如,请参阅here或this answer。
示例强>
这是一个应该完成你要做的事情的例子:
#include <iostream>
#include <getopt.h>
#include <map>
#include <string>
int main (int argc, char** argv)
{
// Create the variables to store your parameters
std::map<std::string, std::string> input_parameters ;
input_parameters["input"] = "default_in" ; // Storage for input
input_parameters["output"] = "default_out" ; // Storage for output
// Create variables to hold your parameters
const struct option longopts[] =
{
{"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'},
{0,0,0,0} // This tells getopt that this is the end
};
// Some parameters for getopt_long
int c(0);
// Get the options from the command line
while (c != -1) {
int option_index(-1) ;
// Read the next command line option
// Note here that the ':' after the 'i' and 'o' denotes that
// it requires an argument
c = getopt_long(argc, argv, "i:o:", longopts, &option_index) ;
// If the option is valid, fill the corresponding value
if ((c>0)&&(option_index>=0)) {
std::cout << option_index << std::endl;
input_parameters[longopts[option_index].name] = optarg ;
}
switch (c) {
case 'i':
// Fill input option
input_parameters["input"] = optarg ;
case 'o':
// Fill output option
input_parameters["output"] = optarg ;
case '?':
// getopt_long printed an error message
break ;
}
}
std::cout << "input = " << input_parameters["input"] << std::endl;
std::cout << "output = " << input_parameters["output"] << std::endl;
return 0 ;
}
请注意,在此处运行此操作会在参数和要传递给它的值之间留一个空格。这将产生以下结果:
$ ./myscript --input inputfile.txt --output outputfile.txt
input = inputfile.txt
output = outputfile.txt
或
$ ./myscript -i inputfile.txt -o outpufile.txt
input = inputfile.txt
output = outputfile.txt
您还可以互换使用--input
和-i
(与--output
和-o
类似)。
开始无耻插件(我自己的CLOptions代码围绕getopt构建)
我实际上对使用boopt,double,int或string参数获取getopt的完整功能所花费的工作量有点不满。我还必须在每个项目中创建一个全新的实现!所以,我把一个名为“CLOptions”的快速类放在一起,这样我就可以#include "CLOptions.h"
在我的代码中(一切都在一个文件中),现在我只需要一行来定义每个附加选项。它还会为您打印帮助信息创建-h
或-help
选项!它包括将每个参数作为bool,double,int或string的功能,具体取决于您定义每个参数的方式。您可以在GitHub here上查看how the above method could be implemented示例。请注意,该类是C ++ 11,并且在编译时需要-std=c++11
(尽管如果有人问,我可以尝试编写C版本。)
虽然我还没有尝试过,但是还有许多其他人设计的其他命令行程序来解决这个问题(例如options或dropt)。你可以通过Google搜索来找到它们。