C++ 命令行传递参数改为内部直接定义参数

探索者v
博客专家认证
2015-05-02 09:38:29

网上下载的源码编译后通过命令行传递参数, 我想把他改为在程序中直接赋值,但是这个代码用了一个param类来处理命令行参数,而且多处用到,我应该怎么处理,正文里用到的para吗太多不可能去掉,直接给argv[0], argv[1], argv[2] 赋值不行,怎么办,怎么办, 求助!!本人新手希望给出较为详细的解答谢谢。

param类的源代码是
//
#include <fstream>
#include <cstdio>
#include "param.h"
#include "common.h"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

namespace CRFPP {
namespace {

void init_param(std::string *help,
std::string *version,
const std::string &system_name,
const Option *opts) {
*help = std::string(COPYRIGHT) + "\nUsage: " +
system_name + " [options] files\n";

*version = std::string(PACKAGE) + " of " + VERSION + '\n';

size_t max = 0;
for (size_t i = 0; opts[i].name; ++i) {
size_t l = 1 + std::strlen(opts[i].name);
if (opts[i].arg_description)
l += (1 + std::strlen(opts[i].arg_description));
max = std::max(l, max);
}

for (size_t i = 0; opts[i].name; ++i) {
size_t l = std::strlen(opts[i].name);
if (opts[i].arg_description)
l += (1 + std::strlen(opts[i].arg_description));
*help += " -";
*help += opts[i].short_name;
*help += ", --";
*help += opts[i].name;
if (opts[i].arg_description) {
*help += '=';
*help += opts[i].arg_description;
}
for (; l <= max; l++) *help += ' ';
*help += opts[i].description;
*help += '\n';
}

*help += '\n';
return;
}
} // namespace

void Param::dump_config(std::ostream *os) const {
for (std::map<std::string, std::string>::const_iterator it = conf_.begin();
it != conf_.end();
++it) {
*os << it->first << ": " << it->second << std::endl;
}
}

bool Param::load(const char *filename) {
std::ifstream ifs(WPATH(filename));

CHECK_FALSE(ifs) << "no such file or directory: " << filename;

std::string line;
while (std::getline(ifs, line)) {
if (!line.size() ||
(line.size() && (line[0] == ';' || line[0] == '#'))) continue;

size_t pos = line.find('=');
CHECK_FALSE(pos != std::string::npos) << "format error: " << line;

size_t s1, s2;
for (s1 = pos+1; s1 < line.size() && isspace(line[s1]); s1++);
for (s2 = pos-1; static_cast<long>(s2) >= 0 && isspace(line[s2]); s2--);
const std::string value = line.substr(s1, line.size() - s1);
const std::string key = line.substr(0, s2 + 1);
set<std::string>(key.c_str(), value, false);
}

return true;
}

bool Param::open(int argc, char **argv, const Option *opts) {
int ind = 0;
int _errno = 0;

#define GOTO_FATAL_ERROR(n) { \
_errno = n; \
goto FATAL_ERROR; } while (0)

if (argc <= 0) {
system_name_ = "unknown";
return true; // this is not error
}

system_name_ = std::string(argv[0]);

init_param(&help_, &version_, system_name_, opts);

for (size_t i = 0; opts[i].name; ++i) {
if (opts[i].default_value) set<std::string>
(opts[i].name, opts[i].default_value);
}

for (ind = 1; ind < argc; ind++) {
if (argv[ind][0] == '-') {
// long options
if (argv[ind][1] == '-') {
char *s;
for (s = &argv[ind][2]; *s != '\0' && *s != '='; s++);
size_t len = (size_t)(s - &argv[ind][2]);
if (len == 0) return true; // stop the scanning

bool hit = false;
size_t i = 0;
for (i = 0; opts[i].name; ++i) {
size_t nlen = std::strlen(opts[i].name);
if (nlen == len && std::strncmp(&argv[ind][2],
opts[i].name, len) == 0) {
hit = true;
break;
}
}

if (!hit) GOTO_FATAL_ERROR(0);

if (opts[i].arg_description) {
if (*s == '=') {
if (*(s+1) == '\0') GOTO_FATAL_ERROR(1);
set<std::string>(opts[i].name, s+1);
} else {
if (argc == (ind+1)) GOTO_FATAL_ERROR(1);
set<std::string>(opts[i].name, argv[++ind]);
}
} else {
if (*s == '=') GOTO_FATAL_ERROR(2);
set<int>(opts[i].name, 1);
}

// short options
} else if (argv[ind][1] != '\0') {
size_t i = 0;
bool hit = false;
for (i = 0; opts[i].name; ++i) {
if (opts[i].short_name == argv[ind][1]) {
hit = true;
break;
}
}

if (!hit) GOTO_FATAL_ERROR(0);

if (opts[i].arg_description) {
if (argv[ind][2] != '\0') {
set<std::string>(opts[i].name, &argv[ind][2]);
} else {
if (argc == (ind+1)) GOTO_FATAL_ERROR(1);
set<std::string>(opts[i].name, argv[++ind]);
}
} else {
if (argv[ind][2] != '\0') GOTO_FATAL_ERROR(2);
set<int>(opts[i].name, 1);
}
}
} else {
rest_.push_back(std::string(argv[ind])); // others
}
}

return true;

FATAL_ERROR:
switch (_errno) {
case 0: WHAT << "unrecognized option `" << argv[ind] << "`"; break;
case 1: WHAT << "`" << argv[ind] << "` requires an argument"; break;
case 2: WHAT << "`" << argv[ind] << "` doesn't allow an argument"; break;
}
return false;
}

void Param::clear() {
conf_.clear();
rest_.clear();
}

bool Param::open(const char *arg, const Option *opts) {
char str[BUF_SIZE];
std::strncpy(str, arg, sizeof(str));
char* ptr[64];
unsigned int size = 1;
ptr[0] = const_cast<char*>(PACKAGE);

for (char *p = str; *p;) {
while (isspace(*p)) *p++ = '\0';
if (*p == '\0') break;
ptr[size++] = p;
if (size == sizeof(ptr)) break;
while (*p && !isspace(*p)) p++;
}

return open(size, ptr, opts);
}

int Param::help_version() const {
if (get<bool>("help")) {
std::cout << help();
return 0;
}

if (get<bool>("version")) {
std::cout << version();
return 0;
}

return 1;
}
}
...全文
422 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
AndyStevens 2015-05-05
  • 打赏
  • 举报
回复
system("crf_learn -f -z");
赵4老师 2015-05-05
  • 打赏
  • 举报
回复
#include <stdio.h>
void test(int argc,char **argv) {
    int i;

    for (i=0;i<argc;i++) {
        printf("argv[%d]==[%s]\n",i,argv[i]);
    }
}
int main() {
    char *myargv[3]={"./crf_learn","-v","yourfiles"};
    int myargc=3;

    test(myargc,(char **)myargv);
    return 0;
}
//argv[0]==[./crf_learn]
//argv[1]==[-v]
//argv[2]==[yourfiles]
//
赵4老师 2015-05-05
  • 打赏
  • 举报
回复
Param par;
Option opt;
int myargc=3;
char *myargv[3]={"./crf_learn","-v","yourfiles"};
par.open(myargc,(char **)myargv,&opt);
探索者v 2015-05-04
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
Param par;
Option opt;
int myargc=3;
char *myargv[3]={"myself.exe","-fpar1","-epar2"};
par.open(myargc,(char **)myargv,&opt);
谢谢前辈的指点,但是这样还是不行,程序的帮助是这样的 Usage: ./crf_learn [options] files -f, --freq=INT use features that occuer no less than INT(default 1) -m, --maxiter=INT set INT for max iterations in LBFGS routine(default 10k) -c, --cost=FLOAT set FLOAT for cost parameter(default 1.0) -e, --eta=FLOAT set FLOAT for termination criterion(default 0.0001) -C, --convert convert text model to binary model -t, --textmodel build also text model file for debugging -a, --algorithm=(CRF|MIRA) select training algorithm -p, --thread=INT number of threads (default auto-detect) -H, --shrinking-size=INT set INT for number of iterations variable needs to be optimal before considered for shrinking. (default 20) -v, --version show the version and exit -h, --help show this help and exit 不设置 options,直接给出file的地址没有问题,但是给他设置上面参数的时候就不行了。
xiaohuh421 2015-05-04
  • 打赏
  • 举报
回复
命令行参数改为内部直接定义参数 你这个说法就是错的. main函数中的命令行参数是由调用时传入的. 而main的调用都是系统行为. 1. 既然你都使用了自定义的串了, 那么你就在main中写成一个局部变量, 不使用main的avrg参数即可. 2. 如果是调试时, 那么可以在VS的工程属性中有一个调试选项, 可以添加调试时的命令行.
幻夢之葉 2015-05-04
  • 打赏
  • 举报
回复
char* myargv[]={"程序名.exe",...}; 第一个是程序的路径啊 比如C盘下 C:\\程序名.exe 如果第一个参数没有做什么关键的就没什么影响
赵4老师 2015-05-04
  • 打赏
  • 举报
回复
Param par;
Option opt;
int myargc=3;
char *myargv[3]={"myself.exe","-fpar1","-epar2"};
par.open(myargc,(char **)myargv,&opt);
探索者v 2015-05-04
  • 打赏
  • 举报
回复
引用 2 楼 mewiteor 的回复:
自己定义个
char* myargv[]={"程序名.exe",...};
然后将main中被param类调用的argc和argv替换成
sizeof myargv/sizeof *myargv
和myargv
现在的情况是必要的参数没有问题, 有可选的参数,前面要加 -f,-e,这种的输入之后就不行,好奇怪,请前辈给予帮助
探索者v 2015-05-04
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
比如将
Param par;
Option opt;
par.open(argc,argv,&opt);
改为
Param par;
Option opt;
int myargc=3;
char *myargv[3]={"myself.exe","par1","par2"};
par.open(myargc,(char **)myargv,&opt);
现在的情况是必要的参数没有问题, 有可选的参数,前面要加 -f,-e,这种的输入之后就不行,好奇怪,请前辈给予帮助
ri_aje 2015-05-04
  • 打赏
  • 举报
回复
自己组装一对 argc, argv 不就行了吗?
赵4老师 2015-05-04
  • 打赏
  • 举报
回复
比如将
Param par;
Option opt;
par.open(argc,argv,&opt);
改为
Param par;
Option opt;
int myargc=3;
char *myargv[3]={"myself.exe","par1","par2"};
par.open(myargc,(char **)myargv,&opt);
707wk 2015-05-03
  • 打赏
  • 举报
回复
先替换掉然后宏定义
mewiteor 2015-05-03
  • 打赏
  • 举报
回复
自己定义个
char* myargv[]={"程序名.exe",...};
然后将main中被param类调用的argc和argv替换成
sizeof myargv/sizeof *myargv
和myargv
AlanBruce 2015-05-02
  • 打赏
  • 举报
回复
argv为啥不行,代码中没看出哪里使用了

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧