Convert char pointer to unsigned char array - c

I want to convert a char pointer to a unsigned char var, I thought I could do that with just casting but it doesn't work:
char * pch2;
//Code that puts something in pc2
part1 = (unsigned char) pch2;
I've the code to this:
result.part1 = (unsigned char *) pch2;
printf("STRUCT %s\n",result.part1);
result is just a struct with unsigned char arrays.
EDIT:
pch2 = strtok( ip, "." );
while( pch2 != NULL ){
printf( "x %d x: %s\n", i, pch2 );
pch2[size-1] = '\0';
if(i == 1)
result.part1 = (unsigned char *) pch2;
if(i == 2)
result.part2 = (unsigned char *) pch2;
if(i == 3)
result.part3 = (unsigned char *) pch2;
if(i == 4)
result.part4 = (unsigned char *) pch2;
i++;
pch2 = strtok (NULL,".");
}
printf("STRUCT %c\n",result.part1);
Struct:
typedef struct
{
unsigned char part1;
unsigned char part2;
unsigned char part3;
unsigned char part4;
} res;

you cast to unsigned char not unsigned char* you forgot the *
part1 = (unsigned char*) pch2;
if pch2 is not null terminated the program will crash, if you're lucky, when you use strlen, so you need to null terminate it first before printing using pch2, try this instead:
pch2[size-1] = '\0'; /* note single quote */
result.part1 = (unsigned char *) pch2;
Update: define your structure like so:
typedef struct
{
const char *part1;
const char *part2
const char *part3;
const char *part4;
} res;
And assign to it without casting at all:
result.part1 = pch2;

You want to do this:
part1 = (unsigned char*) pch2;
Instead of:
part1 = (unsigned char) pch2;

Try something like this:-
char *ph2;
unsigned char *new_pointer = (unsigned char*) ph2;

I want to convert a char pointer to a unsigned char var
Are you sure? Converting pointer to char to unsigned char is not going to do any good - value will get truncated to 1 byte, and it will be meaningless anyway. Maybe you want to dereference a pointer and get value pointed by it - then you should do something like this:
unsigned char part1 = (unsigned char)*pch2;
After your edit I see that part1 is character array - if your program crashes after it is used, you probably fill pch2 incorrectly. Maybe you forgot '\0' terminator?
EDIT:
You see, it is much better now to answer your question having all required information. Do you need to use strtok? Would this be good?
res result;
char* ip = "123.23.56.33";
sscanf(ip, "%hhu.%hhu.%hhu.%hhu", &result.part1, &result.part2, &result.part3, &result.part4);

Found the problem, forgot to cast the char pch2 to unsigned int and then I can printout with %u.
Code:
unsigned int temp;
temp = atoi(pch2);
result.part1 = temp;
printf("Struct: %u\n",result.part1);
Thanks for your help guys!

Related

Basic malloc, array, pointer and assignment error

I have the following code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buf = malloc(sizeof(char *) *3);
char *p = "print";
char *q = "quit";
char *r = "reverse";
buf[0] = p;
buf[1] = q;
buf[2] = r;
printf("%s", buf[0]);
return 0;
}
I think buf will save the address of char variable.
So, as p indicates the address of string, i think i can assign p to buf[0].
But compiler says "assignment makes integer from pointer without a cast".
Why this happens?
first : you are trying to assign a char * to char instead you must use the following code
char **buf = (char **)malloc(sizeof(char *) * 3);
credit #chux

Converting integer to unsigned char* (int 221 to "\xdd")

I have a function which takes unsigned char* as input.
Say for example that I have:
unsigned char* data = (unsigned char*) "\xdd";
int a = 221;
How can I convert my integer a to unsigned char* such that data and my converted a is indistinguishable?
I have tried playing around with sprintf but without any luck, I'm not sure how to handle the "\x" part.
Since 221 is not guaranteed to be a valid value for a char type, the closest thing you can do is:
int a = 221;
unsigned char buffer[10];
sprintf((char*)buffer, "%c", a);
Here's an example program and its output:
#include <stdio.h>
int main()
{
unsigned char* data = (unsigned char*) "\xdd";
int a = 221;
unsigned char buffer[10];
sprintf((char*)buffer, "%c", a);
printf("%d\n", buffer[0] == data[0]);
printf("%d\n", buffer[0]);
printf("%d\n", data[0]);
}
Output:
1
221
221
Update
Perhaps I misunderstood your question. You can also use:
int a = 221;
unsigned char buffer[10] = {0};
buffer[0] = a;
As stated the question does not make sense and is not possible - you don't actually want to convert to const char *, which is a pointer type. Instead you want to convert into an array of chars and then take the address of that array by using its name.
int x = 221;
char buf[5];
snprintf(buf, sizeof buf, "\\x%.2x", x);
/* now pass buf to whatever function you want, e.g.: */
puts(buf);

Casting integers as another char pointer

I'm testing the code below, but the output just says
ptr char = (null)
Any clue why this is happening?
int buf[1024];
buf[0] = 10;
buf[1] = 0;
buf[2] = 1992;
buf[3] = 42;
buf[4] = 5;
char *ptr;
ptr = (char*)buf+2;
printf("ptr char = %s\n",*ptr);
I just experimented on the above code so that I could know part by part what the code below would do.
here is the code I'm working on
int fillNSendHttpReq(int8u seq, char* domain, char* uri, char method, char* contentType, char* otherHeader, int contentLen, char* content, unsigned char timeout, char moreData, char isHttps)
{
int16u encodedLen = moreData?contentLen|0x8000:contentLen;
//if moredata = true then encodelen = contentlenBITWISEOR0x8000
char *ptr = NULL;
int8u buf[1024];
memset(buf, 0, sizeof(buf));
buf[0] = SNIC_HTTP_REQ;
buf[1] = seq;
*((int16u*)&buf[2]) = 0x5000; //swapped
buf[4] = method;
buf[5] = timeout;
if (isHttps) {
buf[0] = SNIC_HTTPS_REQ;//SNIC_HTTPS_REQ = 0
*((int16u*)&buf[2]) = 0xbb01; // 443 swapped
}
ptr = (char*)buf+6; //convert in8u to char * ???
ptr += sprintf(ptr, "%s", domain)+1; //ptr = ptr + strlen(domain)+1
ptr += sprintf(ptr, "%s", uri)+1;
ptr += sprintf(ptr, "%s", contentType)+1;
ptr += sprintf(ptr, "%s", otherHeader)+1;
*((int16u*)ptr) = swap16(encodedLen);
ptr += 2;
if (contentLen)
memcpy(ptr, content, contentLen);
serial_transmit(CMD_ID_SNIC, buf, ptr-(char*)buf+contentLen, ACK_NOT_REQUIRED);
return 0;
the part I don't understand is that ptr-(char*)buf+contentLenwas assigned to the variable defined as int and so that got me confused on where my content went which was a char.
int is of some size. When you add 2 to a char*, the pointer advances by two bytes; to advance it by the size of an int, you’d do (char*)(buf + 2). Two bytes past buf might be buf[1], or it might be half of buf[0], but apparently it points to zero, because that’s what you get by dereferencing ptr later – NULL is 0. When passing a string to printf, you don’t dereference it first.
I don’t really know how to fix that part, though, because it just doesn’t make a lot of sense. If your code is close to your intent, then this is probably what it should be:
char *ptr = (char*)(buf + 2);
printf("ptr char = %s\n", ptr);
in which case it’ll print either zero or one characters with your example buf.
char *ptr;
ptr = (char*)buf+2;
printf("ptr char = %s\n",*ptr);
ptr is a char pointer, so *ptr is the character it points to. You passed a character as parameter while the printf is waiting for a "string" (char pointer) so it crashed
Previously you have assigned ptr = (char*)buf+2; so ptr is now pointing to halfway between buff[0] and buff[1], and *ptr == 0 (since buf[0] = 10;, the third byte in buff is zero regardless of endianness, assuming sizeof(int) >= 4), so it represents a NULL value when printf reads it as a pointer. That's why you see the output
Use this
printf("ptr char = %s\n", ptr);
But then you'll see another empty output since ptr[0] is now '\0'

Printing wrong type for hash value on C

I'm heaving a problem on printing a hash generated with OpenSSL, code (using OpenSSL):
char *computeHash(char *msg){
static char hs[20];
SHA1(msg, strlen(msg), hs);
return hs;
}
int main(){
char *text;
char *hash;
int i;
text = "test";
hash = computeHash(text);
for(i=0;i<20;i++){
printf("%02x",hash[i]);
}
return 0;
}
As returning I'm getting:
$ ./a.out ffffffa94affffff8fffffffe5ffffffccffffffb1ffffff9bffffffa61c4c0873ffffffd3ffffff91ffffffe9ffffff87ffffff982fffffffbbffffffd3
Is that any way to print it right?
Thanks,
The %02x format string is for an integer. But you are printing a character. Also, hash is a char * pointer, you probably want an unsigned char *. How about:
unsigned char *hash_ptr = (unsigned char *) hash;
for(i=0;i<20;i++){
printf("%02x", (int) hash_ptr[i]);
}

How to convert unsigned int(u16) into string value(char *)?

I need to convert u16(unsigned int -2 byte) value into string (not ascii).
How to convert unsigned int(u16) into string value(char *)?
/* The max value of a uint16_t is 65k, which is 5 chars */
#ifdef WE_REALLY_WANT_A_POINTER
char *buf = malloc (6);
#else
char buf[6];
#endif
sprintf (buf, "%u", my_uint16);
#ifdef WE_REALLY_WANT_A_POINTER
free (buf);
#endif
Update: If we do not want to convert the number to text, but to an actual string (for reasons that elude my perception of common sense), it can be done simply by:
char *str = (char *) (intptr_t) my_uint16;
Or, if you are after a string that is at the same address:
char *str = (char *) &my_uint16;
Update: For completeness, another way of presenting an uint16_t is as a series of four hexadecimal digits, requiring 4 chars. Skipping the WE_REALLY_WANT_A_POINTER ordeal, here's the code:
const char hex[] = "0123456789abcdef";
char buf[4];
buf[0] = hex[my_uint16 & f];
buf[1] = hex[(my_uint16 >> 4) & f];
buf[2] = hex[(my_uint16 >> 8) & f];
buf[3] = hex[my_uint16 >> 12];
A uint16_t value only requires two unsigned char objects to describe it. Whether the higher byte comes first or last depends on the endianness of your platform:
// if your platform is big-endian
uint16_t value = 0x0A0B;
unsigned char buf[2];
buf[0] = (value >> 8); // 0x0A comes first
buf[1] = value;
// if your platform is little-endian
uint16_t value = 0x0A0B;
unsigned char buf[2];
buf[0] = value;
buf[1] = (value >> 8); // 0x0A comes last
It's not entirely clear what you want to do, but it sounds to me that what you want is a simple cast.
uint16_t val = 0xABCD;
char* string = (char*) &val;
Beware that the string in general is not a 0-byte terminated C-string, so don't do anything dangerous with it.
You can use sprintf:
sprintf(str, "%u", a); //a is your number ,str will contain your number as string

Resources