How can I store 0xFF to a char in C? - c

How can I store something in this format: "0xff" to a char array after declaring the array. I'll demonstrate what I mean below.
When writing a code such as this, works just fine:
int main (void){
unsigned char array[] = {0xff,0xa4};
return 0;
}
But, what I need is slightly more complicated. I need to assign something such as 0xff to the array after having already declared it. How can I get this to work and obtain the exact same result as in the piece of code above? With the code below I keep receiving the error "multi-character character constant [-Wmultichar]" and "large integer implicitly truncated to unsigned type [-Woverflow]".
int main(void){
unsigned char array[2];
array[0] = '0xff';
array[1] = '0xa4';
return 0;
}

Use array[0] = '\xff'; to set a single char to a hex numerical.
Or array[0] = 0xff; as you did in the first part of your code, successfully.

Related

How to access an integer that is being stored in a char array?

So I have figured out how to store an integer in a char array which I declared as (char arr[4096] = {'\0'};) by casting one of the indices to an integer pointer, but how do I then access this integer that is being stored in the char array afterwards?
I have tried printing the value as an int but it is not working. Below I will show the initial declaration followed by the attempted print statement.
int *metaptr = (int*)(&arr[2]);
*metaptr = numb;
printf("%d\n",&arr[2]);
Basically I am expecting numb's value to be printed but instead an address(presumably) is being printed. How can I access the integer value which I have stored in this char array?
Like this:
printf("%d\n", *metaptr);
or this:
printf("%d\n", *((int*)(&arr[2])));

C "Error: Invalid initializer"

the following short code snippet results in a invalid initializer error, and as a beginner in C, I do not understand why.
unsigned char MES[] = { 0x00, .... };
unsigned char *in[] = &MES;
Is this not the correct way to do it?
&MES is a pointer to an array of unsigned char.
in is an array of pointers to unsigned char.
Try instead :
unsigned char (*in)[] = &MES;
which makes in also a pointer to an array of unsigned char.
I think that what you are trying to achieve is the following:
unsigned char MES[] = { 0x00 };
unsigned char *in = MES;
qualifying in as an array (whose size is unknown) as follow
unsigned char (*in2)[] = &MES;
is not going to add valuable information to it aside that it has a finite size (which is true for any data) and if you print in and in2
printf ("%lx\n", (long unsigned int) in);
printf ("%lx\n", (long unsigned int) in2);
the value shall be the same.
Don't confuse the position of the data with the position of its reference.
Using &MES is like trying to read the position in memory where the position of the array is written. But this does not exist.
Consider the counterexample:
void *reference_to_memoryarea = malloc(3);
void **reference_to_the_reference = &reference_to_memoryarea;
Here the position exists and has a position in memory, where it is stored. And you can write into *reference_to_the_reference and generate a good leak

How do you convert an unsigned int[16] of hexidecimal to an unsigned char array without losing any information?

I have a unsigned int[16] array that when printed out looks like this:
4418703544ED3F688AC208F53343AA59
The code used to print it out is this:
for (i = 0; i < 16; i++)
printf("%X", CipherBlock[i] / 16), printf("%X",CipherBlock[i] % 16);
printf("\n");
I need to pass this unsigned int array "CipherBlock" into a decrypt() method that only takes unsigned char *. How do correctly memcpy everything from the "CipherBlock" array into an unsigned char array without losing information?
My understanding is an unsigned int is 4 bytes and unsigned char 1 byte. Since "CipherBlock" is 16 unsigned integers, the total size in bytes = 16 * 4 = 64 bytes. Does this mean my unsigned char[] array needs to be 64 in length?
If so, would the following work?
unsigned char arr[64] = { '\0' };
memcpy(arr,CipherBlock,64);
This does not seem to work. For some reason it only copies the the first byte of "CipherBlock" into "arr". The rest of "arr" is '\0' thereafter.
An int is at least 16 bits, same as a short in that regard.
It looks like every unsigned int has values 0-255 or 00-FF in your case, which is a safe range for an unsigned char. However, the proper way to convert one to the other is a cast:
for (int i=0; i<16; ++i) arr[i] = (unsigned char) CipherBlock[i];
But you have not specified what kind of data decrypt() expects. From the signature, I suspect integral data (strings are usually char* or const char*) but it's hard to be sure without a context.
Note that you could also do printf("%02X", CipherBlock[i]); for printing.
Why don't you just cast the CipherBlock pointer to unsigned char * and pass that?
decrypt((unsigned char *)CipherBlock);
You need to repack the numbers so you can not use memcpy or cast it directly. Aib has it correct.
unsigned char array[16];
for(int i = 0; i < 16; i++) {
array[i] = CipherBlock[i];
}

Question about a pointer in a program. [C]

Here is the full code of it
#include <stdio.h>
#include <string.h>
void reverse_string(unsigned short *buf, int length)
{
int i;
unsigned short temp;
for (i = 0; i < length / 2; i++)
{
temp = buf[i];
buf[i] = buf[length - i - 1];
buf[length - i - 1] = temp;
}
}
int main(int argc, char **argv)
{
unsigned short* tmp = (unsigned short*)argv[1];
reverse_string(tmp,strlen(argv[1]) / 2);
printf("%s",argv[1]);
return 0;
}
As you can see, in main, we have
unsigned short* tmp = (unsigned short*)argv[1];
Arent pointers supposed to point "to the address of" of a variable? The one above isn't(using the ampersand). Yet the program works as intended.
Why is it like that?
And what does this part mean?
(unsigned short*)argv[1]
argv is a pointer-to-an-array-of-pointers:
argv[0][0] (a char)
argv[0] (a char*)
argv (a char**)
unsigned char* tmp = (unsigned char*)argv[1];
...works, because you're referencing the the second "string" in that set.
Note that in this case, "char" and "unsigned short" might be roughly equivolent depending on the compiler and platform, but it is probably not a good idea to assume that. For example, if you compiled to enable a "unicode" command line, then you might get "short" instead of "char" forwarded to you from the command line. But, that may be a dangerous assumption, as "these days" a "short" is usually 16-bits and a "char" is usually 8-bits.
Addressing the original questions:
argv is an array of pointers, each of which point to a character array. argv[1] is a pointer to the character array with the first argument (i.e. if you run ./program arg1 arg2, the pointer argv[1] points to the string arg1).
The ampersand is used to denote a reference, which is for most purposes the same as a pointer. It is syntactic sugar to make it easy to pass a reference to a variable that you have already declared. The common example is using scanf.
int x = 1;
scanf(..., &x, ...)
is equivalent to
int x = 1;
int *p = &x;
scanf(..., p, ...)
The program itself is designed to flip endianness. It's not sufficient to go character-by-character because you have to flip two bytes at a time (ie short-by-short), which is why it works using shorts.
(unsigned short*)argv[1] instructs the compiler to treat the address as if it were an array of shorts. To give an example:
unsigned char *c = (unsigned char *)argv[1];
c[1]; /*this points to the address one byte after argv*/
unsigned short *s = (unsigned short *)argv[1];
s[1]; /*this points to the address two bytes after argv */
Take a look at a primer on type casting.

Issue with string and pointers

Can somebody tell me why this program does not work?
int main()
{
char *num = 'h';
printf("%c", num);
return 0;
}
The error I get is:
1>c:\users\\documents\visual studio 2010\projects\sssdsdsds\sssdsdsds\sssdsdsds.cpp(4): error C2440: 'initializing' : cannot convert from 'char' to 'char *'
But if I write the code like that:
int main()
{
char num = 'h';
printf("%c", num);
return 0;
}
it's working.
char *num = 'h';
Here, the letter 'h' is a char, which you are trying to assign to a char*. The two types are not the same, so you get the problem that you see above.
This would work:
char *num = "h";
The difference is that here you're using double-quotes ("), which creates a char*.
This would also work:
char letter = 'h';
char* ptrToLetter = &letter;
You should read up on pointers in C to understand exactly what these different constructions do.
char * is a pointer to a char, not the same thing than a single char.
If you have char *, then you must initialize it with ", not with '.
And also, for the formatting representation in printf():
the %s is used for char *
the %c is only for char.
In thefirst case you declared num as a pointer to a char. In the second case, you declare it as a char. In each case, you assign a char to the variable. You can't assign a char to a pointer to a char, hence the error.
'h' = Char
"h" = Null terminated String
int main()
{
char *num = "h";
printf("%s", num); // <= here change c to s if you want to print out string
return 0;
}
this will work
As somebody just said, when you write
char *num = 'h'
The compiler gives you an error because you're trying to give to a pointer a value. Pointers, you know, are just variables that store only the memory address of another variable you defined before. However, you can access to a variable's memory address with the operator:
&
And a variable's pointer should be coerent in type with the element pointed.
For example, here is how should you define correctly a ptr:
int value = 5;
//defining a Ptr to value
int *ptr_value = &value;
//by now, ptr_value stores value's address
Anyway, you should study somewhere how this all works and how can ptrs be implemented, if you have other problems try a more specific question :)
When you are using char *h, you are declaring a pointer to a char variable. This pointer keeps the address of the variable it points to.
In simple words, as you simply declare a char variable as char num='h', then the variable num will hold the value h and so if you print it using printf("%c",num), you will get the output as h.
But, if you declare a variable as a pointer, as char *num, then it cannot actually hold any character value. I can hold only the address of some character variable.
For example look at the code below
void main()
{
char a='h';
char *b;
b=&a;
printf("%c",a);
printf("%c",b);
printf("%u",b);
}
here , we have one char variable a and one char pointer b. Now the variable a may be located somewhere in memory that we do not know. a holds the value h and &a means address of a in memory The statement b=&a will assign the memory address of a to b. Since b is declared as a pointer, It can hold the address.
The statenment printf("%c",b) will print out garbage values.
The statement printf("%u",b) will print the address of variable a in memory.
so there's difference between char num and char *num. You must first read about pointers. They are different from normal variables and must be used very carefully.

Resources