C++ cast char * to unsigned char - c++

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]);

Related

char array to unsigned char *

So i have this function which receives a pointer:
int myfunc( const char *token, unsigned char *plaintext )
I do my stuff and i end up with a char array:
unsigned char my_plaintext[1024];
Now i need to set that pointer (plaintext) to what's in my_plaintext.
I've tried many different ways but i haven't yet figure this one out...
This part is in a cpp file, and i've even tried:
std::string tmpstr( my_plaintext );
But this comes back with:
token_crypto.cpp:131:13: error: invalid conversion from 'char*' to 'unsigned char*' [-fpermissive]
my_plaintext
^~~~~~~~~~~~
And
std::string tmpstr( (char *)my_plaintext );
'�5�B'
this does compiles but the content is all wrong:
EDIT:
The content of my_plaintext is fine:
int myfunc( const char *token, unsigned char *plaintext ) {
unsigned char my_plaintext[1024];
... some processing stuff (specifically gcm_decrypt) to which is pass my_plaintext ...
cout << my_plaintext
// prints: hello:world
but then however i try set the contents of plaintext to whatever is in my_plaintext either fails at compilation or prints some weird characters.
If you know that plaintext already points at an array that is 1024 long (or longer) then you can use memmove():
int myfunc( const char *token, unsigned char *plaintext )
{
unsigned char my_plaintext[1024];
/* ... fill in my_plaintext here ... */
memmove(plaintext, my_plaintext, 1024);
/* ... rest of function ... */
}
Note that the parameters to memmove are destintation and then source rather than the other way round.
It's up to the caller of your function to make sure the pointer they pass in points to at least 1024 bytes.
You can use memcpy() instead in this case, but using memmove() is good practice in general.
The C++ string constructor doesn't take an unsigned char *. See the C++ reference here:
http://www.cplusplus.com/reference/string/string/string/
You need to cast the unsigned char array to a char array. See how to do that here:
How to Convert unsigned char* to std::string in C++?

Concatenating char and string in Arduino

I'm playing with an Arduino board and the samples provided. Trying to get a message I received to be displayed on the LCD. I'm struggling to figure out how to work with some of the pre-built code.
I get the error: invalid conversion from 'const unsigned char*' to 'const char*
I tried modify the payload parameter type but it breaks other references to MessageCallback.
Screen.print() definition in the documentation for the arduino board:
int print(unsigned int line, const char s, bool wrap)
Code:
static int MessageCallback(const unsigned char *payload)
{
int result = 200;
const char screenMsg[100];
strcpy(screenMsg,"Set Temp: ");
strcat(screenMsg,payload);
Screen.print(1, screenMsg, true);
return result;
}
Strcat's arguments are (char *, const char *). You can cast "payload" to a char* by doing "strcat(screenMsg, (char*)payload);". Read Strcat two unsigned char in C.
If you just change to char screenMsg[100]; it should work.
The print function will not change the string you provide to it, is all that
const char s
means.

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 covert string array to char**

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

Unsigned char * data as return type of a function in c++ or c [duplicate]

This question already has answers here:
Can I turn unsigned char into char and vice versa?
(6 answers)
Closed 8 years ago.
I am using visual studio 2010 with CLR(Common language Run Time).
I want to return unsigned char * from compress function to main function but both unsigned char * and char * giving erro
"Error 7 error C2440: '=' : cannot convert from 'char *' to 'unsigned char *' F:\4-2\Thesis\PROJECT\Database Compression Main\Database Compression 2\db_comp_main.cpp 21 "
unsigned char* compressor(char *data)
{
unsigned char *compressed_string;
//With some process I had compressed string of data variable as unsigned char* in variable compressed_string successfully and also printed here. Now want to return it from here.
return compressed_string;
}
int main()
{
unsigned char *main_data;
main_data=compressor("Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");// When I click the error from error list the cursor is put here beside str by visual studio.
printf("%s",main_data);
}
Need to return unsigned char * type data from compressor function. Please help.
Change any of the data type (function argument *data or local variable *main_data) to match the type. Try this
unsigned char *main_data;
Or....
Simple type casting will work to make it working anyway:
unsigned char* compressor(char *data)
{
unsigned char *compressed_string;
compressed_string = (unsigned char*) data;
return compressed_string;
}
int main()
{
char *main_data;
main_data=(char*) compressor("Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");
printf("%s",main_data);
}
Or...
(Changing everything with char*)
There are three char types: (plain) char, signed char and unsigned char. Any char is usually an 8-bit integer* (There's no dedicated "character type" in C language) and in that sense, a signed and unsigned char have a useful meaning (generally equivalent to uint8_t and int8_t). When used as a character in the sense of text, use a char (also referred to as a plain char). This is typically a signed char but can be implemented either way by the compiler. So I think using char* is safe here.
Working Example (considering char * as data type):
char* compressor(char *data)
{
char *compressed_string;
compressed_string = "compressed";
// compressed_string = data;
return compressed_string;
}
int main()
{
char *main_data;
main_data=compressor("Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");
printf("%s",main_data);
}
Also, for simplicity you can use pointer to pointer
void compressor(char **data) {
*data = "compressed"; // assuming the compressed data will be smaller in length of main data, so buffer overflow won't occur
}
int main() {
char *main_data = "Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh";
compressor(&main_data);
printf("%s", main_data);
return 0;
}
Edit
As you asked an alternative to pass by reference, There is no way except pass by reference regarding passing array as function argument. Because when you will write void func(char str[]) you may think you're performing pass by value. But g++ compiler will optimize the statement as void func(char &str[0]) to avoid coping the whole array as function parameter. So in all scenario, you are actually passing by reference.
Here you have to allocate the memory storage for the string. The pointer only point address a not any sequence of byte like array.You have to use calloc or malloc for C and new for C++ to allocate the required memory address. use typecasting to convert the char* to unsigned char*.
#include <bits\stdc++.h>
unsigned char* compressor(unsigned char *data)
{
unsigned char *compressed_string = new unsigned char[100];
//With some process I had compressed string of data variable as unsigned unsigned char** in variable compressed_string successfully and also printed here. Now want to return it from here.
compressed_string = (unsigned char*)"working";
return compressed_string;
}
int main()
{
unsigned char *main_data = new unsigned char[1000];
main_data=compressor((unsigned char*)"Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh");// When I click the error from error list the cursor is put here beside str by visual studio.
printf("%s",main_data);
}
you can use memory as required using a different input variable to avoid unnecessary dynamic allocation.
#include <bits\stdc++.h>
unsigned char* compressor(unsigned char *data) {
unsigned char *compressed_string = new unsigned char[strlen((char*)data)+1];
//With some process I had compressed string of data variable as unsigned char* in variable compressed_string successfully and also printed here. Now want to return it from here.
compressed_string = (unsigned char*)"working";
return compressed_string;
}
int main() {
unsigned char *inp = new unsigned char[1000];
inp = (unsigned char*)"Muhammad Ashikuzzaman.Student from Khulna University Of Engineering And Technology from Bangladesh";
unsigned char *main_data = new unsigned char[strlen((char*)inp)+1];
main_data = compressor(inp);
printf("%s",main_data);
}