简体   繁体   English

在argv主参数中传递const char

[英]passing const char in argv main argument

I have the following: 我有以下内容:

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;

when I compile, I receive: 编译时,我收到:

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

When I make char *INPUTFILE_DATABASE as const char *INPUTFILE_DATABASE I cannot change it anymore, of course not. 当我将char *INPUTFILE_DATABASE设为const char *INPUTFILE_DATABASE我不能再更改它了,当然不能更改。 What am I doing wrong? 我究竟做错了什么? Or is my motiviation not doable in general in this way? 还是我的动力通常无法以这种方式实现?

Finally, I only want to allow to change the input file name but when no file name is given, a standard file name shall be used. 最后,我只想允许更改输入文件名,但是当没有给出文件名时,应使用标准文件名。

You never could change it. 您永远都无法更改它。 It's just that, thanks to old C rules, it looked like you could. 就是这样,由于使用了旧的C规则,因此您看起来可以。 The change in the rules (deprecation in C++98; actually this is illegal since C++11 and won't compile) is to better remind you of that. 规则的更改(在C ++ 98中已弃用;实际上,由于C ++ 11而已,这是非法的,不会编译)是为了更好地提醒您这一点。

To change the string, copy it to something you own, ideally using a std::string , particularly since your grasp of C-strings doesn't appear to be terribly strong (you have a zero-length string you're trying to copy a potentially-non-zero-length string on top of!). 要更改字符串,请将其复制到您拥有的东西上,最好使用std::string ,尤其是由于您对C字符串的掌握似乎并不十分强大(您尝试复制的长度为零的字符串)可能是非零长度的字符串!)。

In fact, I wouldn't copy anything, but re-arrange your logic to conditionally initialise INPUTFILE_DATABASE with something that is still an original constant string, like this: 实际上,我不会复制任何内容,但是会重新安排您的逻辑以有条件地初始化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"
);

Yes, you shouldn't do this. 是的,您不应该这样做。 Instead of this: 代替这个:

char *INPUTFILE_DATABASE = "";

You should do something such as 你应该做一些诸如

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

What happens when you do char *INPUTFILE_DATABASE = ""; 当您执行char *INPUTFILE_DATABASE = "";时会发生什么? is that your char* will point to a position that is made to hold just "" (so probably that's just going to be a byte of value 0 somewhere in the program's binary). 是您的char*将指向仅保留"" (因此可能只是程序二进制文件中某个位置的值为0的字节)。 You can't write to there. 你不能写信到那里。

Also, since this is C++, I would recommend: 另外,由于这是C ++,所以我建议:

std::string INPUTFILE_DATABASE = argv[1];

And instead of if(INPUTFILE_DATABASE[0]=='\\0') you could do if (!INPUTFILE_DATABASE.size()) 而不是if(INPUTFILE_DATABASE[0]=='\\0')您可以执行if (!INPUTFILE_DATABASE.size())

You can use std::string which manages the internal char buffer for you. 您可以使用std::string为您管理内部char缓冲区。 As an example, 举个例子,

#include <string>

std::string INPUTFILE_DATABASE;

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

那就不应该那么复杂了:

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

You shouldn't modify this string either way, making it a char const * prevents you from making a bug. 您不应以任何一种方式修改此字符串,将其设置为char const *可以防止产生错误。

First of all: don't do this, just use std::string instead. 首先:不要这样做,只需使用std::string If helps you a lot in reducing the amounts of stupid bugs that appear with C-style strings. 如果可以帮助您减少C样式字符串出现的愚蠢错误的数量,

To come back to your issue: 回到您的问题:

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;

Off course, working directly with char* requires you to know the amount of characters. 当然,直接与char *一起工作需要您知道字符数。 As mentioned before, std:: string makes things easier: 如前所述, 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;

For this specific case, std::string_view should also work. 对于这种特定情况, std::string_view也应该起作用。

Note that Lightness Races in Orbit posted yet another variant that doesn't require you to potentially allocate memory for this specific case using just char const * 请注意,《 Lightness Races in Orbit中的Lightness Races in Orbit发布了另一种变体,它不需要您仅使用char const *就可以为这种特定情况分配内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM