C++ 在argv主参数中传递常量字符
我有以下资料:C++ 在argv主参数中传递常量字符,c++,string,char,C++,String,Char,我有以下资料: int main(int argc, char *argv[]) { char *INPUTFILE_DATABASE = ""; strcpy(INPUTFILE_DATABASE, argv[1]); if(INPUTFILE_DATABASE[0]=='\0') { cout << "No input file given" << endl; INPUTFILE_DATA
int main(int argc, char *argv[])
{
char *INPUTFILE_DATABASE = "";
strcpy(INPUTFILE_DATABASE, argv[1]);
if(INPUTFILE_DATABASE[0]=='\0')
{
cout << "No input file given" << endl;
INPUTFILE_DATABASE="File_name.csv";
}
cout << "Input file: " << INPUTFILE_DATABASE << endl;
return 0;
当我将char*INPUTFILE\u数据库
设置为const char*INPUTFILE\u数据库
时,我不能再更改它了,当然不能。
我做错了什么?或者我的动机一般来说是不可行的
最后,我只想允许更改输入文件名,但如果没有提供文件名,则应使用标准文件名。是的,您不应该这样做。与此相反:
char *INPUTFILE_DATABASE = "";
你应该做一些事情,比如
char INPUTFILE_DATABASE[32]; // or another size that is sufficent
如果执行char*INPUTFILE_DATABASE=“”代码>是指您的char*
将指向一个位置,该位置被设置为仅容纳“
(因此可能只是程序二进制文件中某个位置的一个值为0
的字节)。你不能给那里写信
也,因为这是C++,我建议:
std::string INPUTFILE_DATABASE = argv[1];
您可以使用if(!INPUTFILE\u DATABASE.size())代替if(INPUTFILE\u DATABASE[0]='\0')
来管理内部char
缓冲区。例如,
#include <string>
std::string INPUTFILE_DATABASE;
if (argc == 1)
INPUTFILE_DATABASE = "File_name.csv";
else
INPUTFILE_DATABASE = argv[1];
#包括
std::字符串输入文件\u数据库;
如果(argc==1)
INPUTFILE\u DATABASE=“File\u name.csv”;
其他的
INPUTFILE_DATABASE=argv[1];
你永远无法改变它。只是,由于旧的C规则,看起来你可以。规则中的更改(C++98中的弃用;实际上这是非法的,因为C++11不会编译)是为了更好地提醒您这一点
要更改字符串,最好使用std::string
,将其复制到您自己的东西上,尤其是因为您对C字符串的掌握似乎不是很强(您有一个零长度的字符串,您正试图在其上复制一个潜在的非零长度字符串!)
事实上,我不会复制任何内容,而是重新安排您的逻辑,使用仍然是原始常量字符串的内容有条件地初始化INPUTFILE\u数据库
,如下所示:
// Use argv[1] if given and non-empty, otherwise a default path
const char* INPUTFILE_DATABASE = (
argc > 1 && argv[1][0] != '\0'
? argv[1]
: "File_name.csv"
);
那就不会再复杂了:
char const* INPUTFILE_DATABASE = argc > 1 ? argv[1] : "File_name.csv";
您不应该以任何方式修改此字符串,使其成为char const*
可以防止您产生错误
首先:不要这样做,只需使用std::string
。If在减少C风格字符串中出现的愚蠢错误方面帮助很大
回到您的问题:
auto i = std::make_unique<char[]>(512); // or more? (Could be calculated at runtime)
std::strcpy(i.get(), argv[1]);
if (i[0]=='\0')
{
cout << "No input file given" << endl;
std::strcpy(i.get(), "filename.csv");
}
cout << "Input file: " << i.get() << std::endl;
对于这种特殊情况,std::string_view
也应该起作用
请注意,Lightness Races in Orbit
发布了另一个变体,它不要求您仅使用char const*
为这种特定情况分配内存,使用std:string代替char*字符串常量,无论您是否将其标记为常量,正如您所看到的,您应该始终使用const
。除此之外,您还试图strcpy
到一个只分配了一个空字节的位置,因此您不仅试图写入只读内存,而且还出现了溢出。为什么所有的否决票都被否决?这个问题问得很好。如果您搜索,可能是重复的,尽管我没有看到任何人链接到原始文件。但当我这样做时,我得到:错误:将“const char[27]”分配给“char[200]”INPUTFILE\u DATABASE=“file\u name.csv”时,类型不兼容;如果要使用c风格的字符串,仍然必须使用strcpy。所有其他答案都没有帮助,也不完整(const char*不是char*)。@MatthieuBrucher除非在这里使用string
,否则会有过多的杀伤力,根本没有必要。”“不是0字节,它仍然包含'\0'指针,在这里就足够了,不需要分配内存和复制字符串。没错,虽然我不认为这会成为性能瓶颈。argc>1&&argv[1][0]!='\0'
(或使用strlen
以清晰显示),但可以
auto i = std::make_unique<char[]>(512); // or more? (Could be calculated at runtime)
std::strcpy(i.get(), argv[1]);
if (i[0]=='\0')
{
cout << "No input file given" << endl;
std::strcpy(i.get(), "filename.csv");
}
cout << "Input file: " << i.get() << std::endl;
auto i = std::string(argc[1]);
if (i.empty())
{
cout << "No input file given" << endl;
i = "filename.csv";
}
cout << "Input file: " << i << std::endl;