代码之家  ›  专栏  ›  技术社区  ›  Ben

在argv主参数中传递const char

c++
  •  -1
  • Ben  · 技术社区  · 7 年前

    我有以下几点:

    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 回复  |  直到 7 年前
        1
  •  1
  •   Blaze    7 年前

    是的,你不应该这样做。而不是这个:

    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_DATABASE[0]=='\0') 你可以做到 if (!INPUTFILE_DATABASE.size())

        2
  •  3
  •   Lightness Races in Orbit    7 年前

    你永远无法改变它。只是,多亏了旧的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"
    );
    
        3
  •  1
  •   lubgr    7 年前

    你可以使用 std::string 管理内部 char 为你提供缓冲。作为一个例子,

    #include <string>
    
    std::string INPUTFILE_DATABASE;
    
    if (argc == 1)
       INPUTFILE_DATABASE = "File_name.csv";
    else
       INPUTFILE_DATABASE = argv[1];
    
        4
  •  1
  •   Maxim Egorushkin    7 年前

    那就不应该再复杂了:

    char const* INPUTFILE_DATABASE = argc > 1 ? argv[1] : "File_name.csv";
    
        5
  •  1
  •   JVApen    7 年前

    您不应该以任何方式修改此字符串,使其成为 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 发布了另一个变体,它不要求您使用 字符数