在argv主参数中传递const char

时间:2018-12-17 10:35:15

标签: c++

我有以下内容:

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;

我编译时收到:

warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
  char *INPUTFILE_DATABASE = "";

当我将char *INPUTFILE_DATABASE设置为const char *INPUTFILE_DATABASE时,我当然不能再更改了。 我究竟做错了什么?还是我的动力通常无法通过这种方式实现?

最后,我只想允许更改输入文件名,但是当没有给出文件名时,将使用标准文件名。

5 个答案:

答案 0 :(得分:3)

您永远无法更改它。就是这样,由于使用了旧的C规则,您可以看起来像。规则的更改(在C ++ 98中已弃用;实际上,由于C ++ 11而已,这是非法的,不会编译)是为了更好地提醒您。

要更改字符串,请将其复制到您拥有的东西上,最好使用std::string,尤其是因为您对C字符串的掌握似乎并不十分强大(您拥有零长度的字符串,重新尝试在其顶部复制一个可能为非零长度的字符串!)。

事实上,我不会复制任何内容,但会重新安排您的逻辑以有条件地 初始化INPUTFILE_DATABASE,而该内容仍然是原始的常量字符串,例如:

// 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"
);

答案 1 :(得分:1)

是的,您不应该这样做。代替这个:

char *INPUTFILE_DATABASE = "";

您应该做类似

的事情
char INPUTFILE_DATABASE[32]; // or another size that is sufficent

当您进行char *INPUTFILE_DATABASE = "";时会发生什么,就是您的char*将指向一个仅持有""的位置(因此很可能只是一个值的字节{ {1}}在程序二进制文件的某个位置)。您不能在那儿写信。

而且,因为这是C ++,所以我建议:

0

您可以std::string INPUTFILE_DATABASE = argv[1]; 代替if(INPUTFILE_DATABASE[0]=='\0')

答案 2 :(得分:1)

您可以使用std::string来为您管理内部char缓冲区。例如,

#include <string>

std::string INPUTFILE_DATABASE;

if (argc == 1)
   INPUTFILE_DATABASE = "File_name.csv";
else
   INPUTFILE_DATABASE = argv[1];

答案 3 :(得分:1)

它应该再复杂不过了

char const* INPUTFILE_DATABASE = argc > 1 ? argv[1] : "File_name.csv";

答案 4 :(得分:1)

您不应以任何一种方式修改此字符串,将其设置为char const *可以防止产生错误。

首先:请勿执行此操作,只需使用std::string即可。如果可以帮助您减少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;

当然,直接与char *一起工作需要您知道字符数。如前所述,std:: string使事情变得简单:

auto i = std::string(argc[1]);
if (i.empty())
    {
        cout << "No input file given" << endl;
        i = "filename.csv";
    }
cout << "Input file: " << i << std::endl;

在这种情况下,std::string_view也应该起作用。

请注意,Lightness Races in Orbit发布了另一种变体,它不需要您仅使用char const *就可以为这种特定情况分配内存