how to covert string array to char** - c++

I want to send the values manually here
void processArgs(int argc, char** argv);
if I sending like this
char* cwd[] = {"./comDaemon", "--loggg=pluginFramework:debug"};
parser->processArgs(2, cwd);
compiler showing warning as
warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
char* cwd[] = {"./comDaemon", "--loggg=pluginFramework:debug"};

Others have noted that the problem is you're trying to pass string literals (which are const) to a function that takes a non-const char ** argument. If what you want is to create non-const strings that you can pass to your non-const arg function, you need explicit char arrays (which you can initialize with string literals):
char arg0[] = "./comDaemon";
char arg1[] = "--loggg=pluginFramework:debug";
char *cwd[] = { arg0, arg1 };
you could even do this all on one line:
char arg0[] = "./comDaemon", arg1[] = "--loggg=pluginFramework:debug", *cwd[] = { arg0, arg1 };

If the function you're passing cwd to expects char ** argument, instead of const char **, here is one way:
char *cwd[] = { const_cast<char *>("value1"), const_cast<char *>("value2") };

Related

How would I pass a string to a function argument defined as const unsigned char*?

I copied Base64 encode/decode functions from Stack Overflow. The decode function works great. My problem is with the encode. I get the following error using Visual Studio 2022:
error C2664: 'std::string Base64_encode(const unsigned char *,size_t)': cannot convert argument 1 from 'const _Elem *' to 'const unsigned char *'
Code snippet:
string Base64_decode(const void* data, const size_t len);
string Base64_encode(const unsigned char* src, size_t len);
int main(int argc, char* argv[])
{
string lsOriginal;
string lsEncoded;
string lsDecoded;
lsEncoded = Base64_encode(lsOriginal.c_str(), lsOriginal.size());
lsDecoded = Base64_decode(lsBase64.c_str(), lsBase64.size());
I tried using reinterpret_cast but I couldn't get it to work. I've never used it before so I'm struggling to get it to compile.
The problem is that std::string::c_str returns a const char* and your function Base64_encode takes an const unsigned char*but there is no implicit conversion from a const char* to const unsigned char*.
To solve this you could use reinterpret_cast as shown below:
Base64_encode(reinterpret_cast<const unsigned char *>(lsOriginal.c_str()), lsOriginal.size());
Working demo
You can even change the functions to so that their first parameter is a const std::string&. Then there will be no need to have the second parameter corresponding to size since we can use std::string::size member function.
//------------------------vvvvvvvvvvvvvvvvvv------------------->first parameter is lvalue reference to const std::string
std::string Base64_encode(const std::string& src)
//----------------------------------------------^-------------->no need for having second parameter
{
return "fd";//return something
}
int main(int argc, char* argv[])
{
std::string lsOriginal = "fdfd";
std::string lsEncoded;
//--------------------------vvvvvvvvv---------------------->pass the original string by reference
lsEncoded = Base64_encode(lsOriginal);
}

How to declare a variable as char* const*?

I have a bluez header file get_opt.h where argv is an argument:
extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,.....
which requires char* const* for argv. Because the unit is called from a different file I was trying to emulate argv but whatever permutation of declaring char, const and * is used I get unqualified-id or the compiler moans about not converting to char* const*. I can get const char * easily, of course. char const * argv = "0"; compiles OK in Netbeans with C++14 but
char * const * argv = "0";
produces
"error: cannot convert 'const char *' to 'char * const *'" in initialisation (sic).
How do you declare char* const* or am I mixing C with C++ so I'm up the wrong tree?
Let's review the pointer declarations:
char * -- mutable pointer to mutable data.
char const * -- mutable pointer to constant data.
char * const -- constant pointer to mutable data.
char const * const -- constant pointer to constant data.
Read pointer declarations from right to left.
Looking at the descriptions, which kind of pointer do you want?
Because void main(void) is in a different file I was trying to emulate
argv
void main(void) is not the correct main function declaration. The main function has to have int return value.
Simply change the void main(void) to int main(int argc, char **argv) in that "other" file.
It does not require char const * to be passed to. Do not change the type of the main function arguments.
int getopt_long (int ___argc, char * const *___argv);
int main(int argc, char **argv)
{
printf("%d\n", getopt_long(argc, argv));
}
Both language compile fine:
https://godbolt.org/z/5To5T931j
Credit #JaMiT above
[I don't know how to accept a commment]
Also, you might want to notice how you can remove the call to getopt_long() from that example while retaining the error (it's motivation for your declaration, but not the source of your issue). If you think about your presentation enough, you might realize that your question is not how to declare a char* const* but how to initialize it. Due to arrays decaying to a pointer, you could declare an array of pointers (char* const argv[]) instead of a pointer to pointer (char* const * argv). See The 1D array of pointers way portion of A: 2D Pointer initialization for how to initialize such a beast. Beware: given your setup, the "2D array way" from that answer is not an option. Reminder: The last pointer in the argument vector is null; argv[argc] == nullptr when those values are provided by the system to main().

Argument of type "unsigned char *" is incompatible with parameter of type "const char *"

I was using the Decoder for Microsoft Script Encoder. It works perfectly well when I run it in Codeblocks. But when I run it in Visual Studio, it shows me the following errors
Snippet 1:
char decodeMnemonic(unsigned char *mnemonic)
{
int i = 0;
while (entities[i].entity != NULL)
{
**if (strcmp(entities[i].entity, mnemonic) == 0)**
**//Error 1: cannot convert argument 2 from 'unsigned char *'
// to 'const char *'**
return entities[i].mappedchar;
i++;
}
printf("Warning: did not recognize HTML entity '%s'\n", mnemonic);
return '?';
}
I had to integrate the Decoder in a program, so instead of passing the filenames as command line arguments, I have given their filepaths myself in the code.
Snippet 2:
int main()
{
unsigned char *inname = "C:\\Users\\Karthi\\Desktop\\Project Winter 2018-19\\poweliks_sample\\poweliks_encoded_js.bin";
unsigned char *outname = "C:\\Users\\Karthi\\Desktop\\Project Winter 2018-19\\poweliks_sample\\decoded1.txt";
unsigned int cp = 0;
//**Error 2: 'initializing': cannot convert from 'const char [87]' to 'unsigned char *'**
You can use reinterpret_cast (for unsigned char* to const char*). But if you go from const unsigned char* to a non const type, you have to use const_cast first, since reinterpret_cast cannot cast away a const.
The paragraph below gives a brief overview, why your code did not work.
According to C99 Standard (similiar to other C standards), a string literal has static storage duration and its type is char[] The standard says:
If the program attempts to modify such an array, the behavior is undefined.
The reason why your program worked, when you used argv is, that argv is not considered as an array of string literals. This means you can modify them.
Here are the solutions for your problems:
Snippet 1:
strcmp is a method to compare two C Strings. It expects const char* types.
int strcmp ( const char * str1, const char * str2 );
You have two option to solve it:
Declare your method like this
char decodeMnemonic(const char *mnemonic)
Use C++Strings and declare your method like this
char decodeMnemonic(std::string mnemonic)
If you use the second solutions you have to call the c_str()-Method to use it in strcmp
if (strcmp(entities[i].entity, mnemonic.c_str()) == 0)
Or you use only C++-String: read here how to use it: http://www.cplusplus.com/reference/string/string/compare/
Snippet 2: You can't use it like this because you have string literals which are arrays constant characters.
Please use C++-Strings. You work with C++, so use his features (https://www.geeksforgeeks.org/stdstring-class-in-c/)
Anyway if you want to use it C-like: https://www.programiz.com/c-programming/c-strings
char c[] = "abcd";
char c[50] = "abcd";
Or with const (C++)
char *str1 = "string Literal";
const char *str2 = "string Literal";

How to declare a pointer to pointer to constant in C++?

I'm trying to write a function to parse command line arguments. This is the function declaration:
void parse(int, char const **);
Just in case, I have also tried (const char)**, const char **, and cchar ** using a typedef const char cchar. However, all of these (as expected, since they should all be identical) result in an error if I pass a char ** into the function, as in:
void main(int argc, char **argv) {
parse(argc, argv);
The error I get from GNU's compiler is error: invalid conversion from 'char**' to 'const char**' and the one from Clang is candidate function not viable: no known conversion from 'char **' to 'const char **' for 2nd argument.
I have seen such solutions suggested as declaring a pointer to a const pointer to char (const char * const *), but I don't want either pointer to be const because I want to be able to modify the pointer so I can iterate over an argument using for(; **argv; ++*argv). How can I declare a "non-const pointer to non-const pointer to const char"?
The function should be declared as:
void parse(int, char const * const *);
In C++, char ** can implicitly add const at all pointer depths, so you can call it as parse(argc, argv).
In C, const can only be added at the first pointer depth (this is a design defect in the language). Here is a dedicated thread. So you have to call the function as: parse(argc, (char const * const *)argv); unfortunately.
The safest signature that prevents modification of the arguments whilst allowing any other const combination to call the function is this:
parse(int argc, char const* const* argv);
That means that argv is a pointer to a const pointer to a const char
You can happily iterate over the parameters like this:
for(auto arg = argv + 1; *arg; ++arg)
{
if(!std::strcmp(*arg, "--help"))
return print_help();
else if(!std::strcmp(*arg, "-v") || !std::strcmp(*arg, "--verbose"))
verbose_flag = true;
// ... etc...
}
Notice there is no need to accept the variable int argc because the array of character arrays is null terminated.
So I normally use this:
struct config
{
// program options and switches
};
config parse_commandline(char const* const* argv);

C++ cast char * to unsigned char

I am working in a c++ project where I have to use < openssl/sha.h> and I am using in particular the SHA1 function. My problem is, that the function receives unsigned char[], and I need to get processed parameters passed as arguments to the program:
int main(int argc, char* argv[])
{
unsigned char message[] = argv[1];
/* program continues using message */
}
And the error I am getting is the following:
error: array initializer must be an initializer list or string literal
const unsigned char message[] = argv[1];
^
So I am not getting to cast appropiately the argument input to the 'message' variable, to make the appropiate call to SHA1 function.
Thanks!!
An array cannot be initialized from a pointer. You should probably use an unsigned char * instead:
unsigned char *message = reinterpret_cast<unsigned char *>(argv[1]);