By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,799 Members | 1,376 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,799 IT Pros & Developers. It's quick & easy.

convert string of hex characters to char

P: n/a
Hello,

I did a quick google search and nothing that was returned is quite
what I am looking for. I have a 200 character hexadecimal string that
I need to convert into a 100 character string.

This is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
char *temp=
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3000000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3";
char *toHex, *output[100];
unsigned long nVal;
int i,j;

for (i=0; i<100; i++){
strcpy(toHex,&temp[j]);
strcpy(toHex,&temp[j+1]);
nVal = strtoul(toHex, NULL, 16);
output[i] = (char*)nVal;
j=j+2;
}
printf("output = %d \n", output);
return 0;
}

This program is supposed to take the first two characters from temp
and convert the hex 2b to char which is +. Then it gets the next two
characters and repeats.

I compiled with gcc test.c -o test
When I run test I get:
segmentation fault

What did I do wrong?
Thanks,
Oct 7 '08 #1
Share this Question
Share on Google+
14 Replies


P: n/a
On Oct 7, 11:53*am, rtillm...@gmail.com wrote:
Hello,

I did a quick google search and nothing that was returned is quite
what I am looking for. *I have a 200 character hexadecimal string that
I need to convert into a 100 character string.

This is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
* char *temp=
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b*2a920000b73aedc3f247839c c3000000203032577ef6a7325629024b0b0a0abc0b75392040 b*c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839 cc3";
* char *toHex, *output[100];
The above addresses do not point to allocated space.
* unsigned long nVal;
* int i,j;

* for (i=0; i<100; i++){
* * strcpy(toHex,&temp[j]);
strcpy() keeps going until it finds a null terminator. You are moving
201 characters into a random location in memory. Furthermore, j is
uninitialized.
* * strcpy(toHex,&temp[j+1]);
See above.
* * nVal = strtoul(toHex, NULL, 16);
* * output[i] = (char*)nVal;
The above cast is utter nonsense.
* * j=j+2;
* }
* printf("output = %d \n", output);
Wrong format specifier.
* return 0;

}

This program is supposed to take the first two characters from temp
and convert the hex 2b to char which is +. *Then it gets the next two
characters and repeats.

I compiled with gcc test.c -o test
When I run test I get:
segmentation fault

What did I do wrong?
Some diagnostic tools applied to the code:

c:\tmp>lin tt.c

c:\tmp>"C:\Lint\Lint-nt" +v -i"C:\Lint" std.lnt -os(_LINT.TMP)
tt.c
PC-lint for C/C++ (NT) Vers. 8.00u, Copyright Gimpel Software
1985-2006

--- Module: tt.c (C)

c:\tmp>type _LINT.TMP | more

--- Module: tt.c (C)

_

"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7bí2a920000b73aedc3f247839c c3000000203032577ef6a7325629024b0b0a0abc0b75392040 bíc3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f2478
39cc3";
tt.c(8) : Info 1776: Converting a string literal to char * is not
const safe
(initialization)
_
strcpy (toHex, &temp[j]);
tt.c(16) : Warning 530: Symbol 'toHex' (line 9) not initialized ---
Eff. C++
3rd Ed. item 4
tt.c(9) : Info 830: Location cited in prior message
_
strcpy (toHex, &temp[j]);
tt.c(16) : Warning 530: Symbol 'j' (line 11) not initialized --- Eff. C
++ 3rd
Ed. item 4
tt.c(11) : Info 830: Location cited in prior message
_
printf ("output = %d \n", output);
tt.c(22) : Warning 626: argument no. 2 inconsistent with format
_
}
tt.c(24) : Note 953: Variable 'toHex' (line 9) could be declared as
const ---
Eff. C++ 3rd Ed. item 3
tt.c(9) : Info 830: Location cited in prior message
_
}
tt.c(24) : Note 953: Variable 'temp' (line 7) could be declared as
const ---
Eff. C++ 3rd Ed. item 3
tt.c(7) : Info 830: Location cited in prior message
_
}
tt.c(24) : Note 954: Pointer variable 'temp' (line 7) could be
declared as
pointing to const --- Eff. C++ 3rd Ed. item 3
tt.c(7) : Info 830: Location cited in prior message

---
output placed in _LINT.TMP

c:\tmp>splint tt.c tt.spl
Splint 3.1.1 --- 12 Mar 2007

Finished checking --- 3 code warnings

c:\tmp>type tt.spl
tt.c: (in function main)
tt.c(16,28): Variable j used before definition
An rvalue is used that may not be initialized to a value on some
execution
path. (Use -usedef to inhibit warning)
tt.c(16,15): Unallocated storage toHex passed as out parameter to
strcpy: toHex
tt.c(22,29): Format argument 1 to printf (%d) expects int gets char *
[100]:
output
Type of parameter is not consistent with corresponding code in
format string.
(Use -formattype to inhibit warning)
tt.c(22,22): Corresponding format code
c:\tmp>type tt.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *temp =

"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7bí2a920000b73aedc3f247839c c3000000203032577ef6a7325629024b0b0a0abc0b75392040 bíc3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f2478
39cc3";
char *toHex, *output[100];
unsigned long nVal;
int i, j;
for (i = 0; i < 100; i++)
{
strcpy (toHex, &temp[j]);
strcpy (toHex, &temp[j + 1]);
nVal = strtoul (toHex, NULL, 16);
output[i] = (char *) nVal;
j = j + 2;
}
printf ("output = %d \n", output);
return 0;
}

c:\tmp>

Perhaps something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
const unsigned char temp[]=
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b*
2a920000b73aedc3f247839cc3000000203032577ef6a73256 29024b0b0a0abc0b75392040b*
c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3";
unsigned char toHex[3]={0}, output[((sizeof temp) >1) + 1];
unsigned long nVal;
int i,j;

for (i=0, j=0; i<100; i++, j+=2){
toHex[0] = temp[j];
toHex[1] = temp[j+1];
nVal = strtoul(toHex, NULL, 16);
output[i] = (unsigned char)nVal;
printf("%02x ", output[i]);
if ((i+1) % 26 == 0) putchar('\n');
}
putchar('\n');
return 0;
}

Oct 7 '08 #2

P: n/a
rt*******@gmail.com wrote:
Hello,

I did a quick google search and nothing that was returned is quite
what I am looking for. I have a 200 character hexadecimal string that
I need to convert into a 100 character string.

This is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
char *temp=
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3000000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3";
char *toHex, *output[100];
unsigned long nVal;
int i,j;

for (i=0; i<100; i++){
strcpy(toHex,&temp[j]);
Bzzzt! There are at least three things wrong here. First, you
have not given any value to the pointer variable toHex, so its value
is indeterminate: it "contains garbage" or "points to a random place,"
and you have no idea where you're trying to store the data you copy
out of temp. Second, you have not given any value to the integer
variable j, so its value is also indeterminate: it "holds a random
value" and you have no idea where you're trying to copy from. And
third, strcpy() is the wrong function to use if you're trying to copy
single characters: It will start with the first character you point it
at and just keep chugging along until it has copied a '\0' character.

Suggested fix: Change toHex from a pointer to an array of three
characters, initialize j to zero before the loop, and replace the
two strcpy() calls with

toHex[0] = temp[j];
toHex[1] = temp[j+1];
toHex[2] = '\0';

(There are snazzier ways to write this, but I'm trying to stick with
your original terminology for clarity's sake.)
strcpy(toHex,&temp[j+1]);
nVal = strtoul(toHex, NULL, 16);
output[i] = (char*)nVal;
Here's another problem: output is an array of 100 pointer variables,
but your trying to store actual char values in them. I imagine that the
compiler complained about an earlier version of the code, and that you
added the (char*) cast to silence it. Unfortunately, this is almost
always the wrong thing to do: The right thing is to step back and ask
why the compiler is complaining.

Suggested fix: Change output to an array of char instead of an
array of char*. Also, try to figure out what you intend to do with
all these characters; at the moment, you're doing almost nothing.
j=j+2;
}
printf("output = %d \n", output);
Another problem: output is an array of char* (or an array of char
with the change suggested above), and the "%d" specifier wants ...
Right you are, it wants one integer. Since when is a 100-place
array the same as one integer?

Suggested fix: Get rid of output altogether, put the printf
call inside the loop (you may want to make adjustments to the format),
and print out each nVal as you compute it.
return 0;
}

This program is supposed to take the first two characters from temp
and convert the hex 2b to char which is +. Then it gets the next two
characters and repeats.

I compiled with gcc test.c -o test
When I run test I get:
segmentation fault

What did I do wrong?
For extra credit and another approach to the problem, study the
sscanf function and consider how you might use a "%2x" specifier.

--
Er*********@sun.com
Oct 7 '08 #3

P: n/a
I did a quick google search and nothing that was returned is quite
what I am looking for. *I have a 200 character hexadecimal string that
I need to convert into a 100 character string.
This is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
* char *temp=
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b*2a920000b73aedc3f247839c c3000000203032577ef6a7325629024b0b0a0abc0b75392040 b*c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839 cc3";
* char *toHex, *output[100];

The above addresses do not point to allocated space.
Ah, yes I see it now. It was starting right at me.
* unsigned long nVal;
* int i,j;
* for (i=0; i<100; i++){
* * strcpy(toHex,&temp[j]);

strcpy() keeps going until it finds a null terminator. *You are moving
201 characters into a random location in memory. *Furthermore, j is
uninitialized.
* * strcpy(toHex,&temp[j+1]);

See above.
* * nVal = strtoul(toHex, NULL, 16);
* * output[i] = (char*)nVal;

The above cast is utter nonsense.
* * j=j+2;
* }
* printf("output = %d \n", output);

Wrong format specifier.
* return 0;
}
This program is supposed to take the first two characters from temp
and convert the hex 2b to char which is +. *Then it gets the next two
characters and repeats.
I compiled with gcc test.c -o test
When I run test I get:
segmentation fault
What did I do wrong?

Some diagnostic tools applied to the code:

c:\tmp>lin tt.c
output deleted
c:\tmp>splint tt.c tt.spl
output deleted

It looks like there is a linux version of splint. I will start to use
it.

Thank you for the fixed code. I will try it tomorrow and let you know
if I get it working.
Oct 7 '08 #4

P: n/a
I did a quick google search and nothing that was returned is quite
what I am looking for. *I have a 200 character hexadecimal string that
I need to convert into a 100 character string.
This is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
* char *temp=
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3000000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3";
* char *toHex, *output[100];
* unsigned long nVal;
* int i,j;
* for (i=0; i<100; i++){
* * strcpy(toHex,&temp[j]);

* * *Bzzzt! *There are at least three things wrong here. *First, you
have not given any value to the pointer variable toHex, so its value
is indeterminate: it "contains garbage" or "points to a random place,"
and you have no idea where you're trying to store the data you copy
out of temp.
Yeah I see that now.
*Second, you have not given any value to the integer
variable j, so its value is also indeterminate: it "holds a random
value" and you have no idea where you're trying to copy from.
I could have sworn that when you use gcc to compile a program the
variables are initialized to zero or Null. I read the linux-kernel
mail list and see messages that say NOT to initialize variables as it
isn't needed and just adds bloat to the executable. Oh well.
>*And
third, strcpy() is the wrong function to use if you're trying to copy
single characters: It will start with the first character you point it
at and just keep chugging along until it has copied a '\0' character.

* * *Suggested fix: Change toHex from a pointer to an array of three
characters, initialize j to zero before the loop, and replace the
two strcpy() calls with

* * * * toHex[0] = temp[j];
* * * * toHex[1] = temp[j+1];
* * * * toHex[2] = '\0';

(There are snazzier ways to write this, but I'm trying to stick with
your original terminology for clarity's sake.)
Thank you for sticking to the original code.
* * strcpy(toHex,&temp[j+1]);
* * nVal = strtoul(toHex, NULL, 16);
* * output[i] = (char*)nVal;

* * *Here's another problem: output is an array of 100 pointer variables,
but your trying to store actual char values in them. *I imagine that the
compiler complained about an earlier version of the code, and that you
added the (char*) cast to silence it. *
That is exactly what I did.
Unfortunately, this is almost
always the wrong thing to do: The right thing is to step back and ask
why the compiler is complaining.

* * *Suggested fix: Change output to an array of char instead of an
array of char*. *Also, try to figure out what you intend to do with
all these characters; at the moment, you're doing almost nothing.
* * j=j+2;
* }
* printf("output = %d \n", output);

* * *Another problem: output is an array of char* (or an array of char
with the change suggested above), and the "%d" specifier wants ...
Right you are, it wants one integer. *Since when is a 100-place
array the same as one integer?

* * *Suggested fix: Get rid of output altogether, put the printf
call inside the loop (you may want to make adjustments to the format),
and print out each nVal as you compute it.
* return 0;
}

* * *For extra credit and another approach to the problem, study the
sscanf function and consider how you might use a "%2x" specifier.
I use sprintf elsewhere to store the hex version of something. I am
not in front of my PC at the moment.

Thanks for the tips. I will post when I figure it all out.

Thanks,
Oct 7 '08 #5

P: n/a
rt*******@gmail.com writes:
[...]
I could have sworn that when you use gcc to compile a program the
variables are initialized to zero or Null. I read the linux-kernel
mail list and see messages that say NOT to initialize variables as it
isn't needed and just adds bloat to the executable. Oh well.
[...]

Objects with static storage duration, if they're not explicitly
initialized, are implicitly initialized to 0 with the appropriate type
(0 for integers, 0.0 for floating-point, NULL (not Null) for pointers,
applied recursively to struct and union members and array elements).
This applies to objects declared outside any function, and to objects
declared within a function with the "static" keyword.

Objects with automatic storage duration, if they're not explicitly
initialized, are not implicitly initialized. Their initial values
will be garbage.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 7 '08 #6

P: n/a
[...]I could have sworn that when you use gcc to compile a program the
variables are initialized to zero or Null. *I read the linux-kernel
mail list and see messages that say NOT to initialize variables as it
isn't needed and just adds bloat to the executable. *Oh well.

[...]

Objects with static storage duration, if they're not explicitly
initialized, are implicitly initialized to 0 with the appropriate type
(0 for integers, 0.0 for floating-point, NULL (not Null) for pointers,
applied recursively to struct and union members and array elements).
This applies to objects declared outside any function, and to objects
declared within a function with the "static" keyword.

Objects with automatic storage duration, if they're not explicitly
initialized, are not implicitly initialized. *Their initial values
will be garbage.
I learned something new today.

Thanks,
Oct 8 '08 #7

P: n/a
On 8 Oct, 00:02, rtillm...@gmail.com wrote:
I imagine that the
compiler complained about an earlier version of the code, and that you
added the (char*) cast to silence it. *

That is exactly what I did.
break this habit

--
Nick Keighley
Oct 8 '08 #8

P: n/a
For extra credit and another approach to the problem, study the
sscanf function and consider how you might use a "%2x" specifier.
You mean something like this:
for (i=0, j=0; i<76; i++, j+=2){
sscanf(&temp[j], "%2x", &output[i]);
printf("%02x ", output[i]);
}

Thank you to everyone for your help.
Oct 8 '08 #9

P: n/a
On Oct 8, 3:38 pm, rtillm...@gmail.com wrote:
For extra credit and another approach to the problem, study the
sscanf function and consider how you might use a "%2x" specifier.

You mean something like this:
for (i=0, j=0; i<76; i++, j+=2){
sscanf(&temp[j], "%2x", &output[i]);
printf("%02x ", output[i]);
}

Thank you to everyone for your help.
The compiler threw a:
warning: format '%2x' expects type 'unsigned int *', but argument 3
has type 'unsigned int'

so I did the following:
sscanf(&temp[j], "%2x", (unsigned int*)&output[i]);

It silences the compiler and the output is the same but I wanted to
post to make sure this was the right way to handle the warning.

So is this right?
Oct 8 '08 #10

P: n/a
rt*******@gmail.com writes:
>[...]I could have sworn that when you use gcc to compile a program the
variables are initialized to zero or Null. *I read the linux-kernel
mail list and see messages that say NOT to initialize variables as it
isn't needed and just adds bloat to the executable. *Oh well.

[...]

Objects with static storage duration, if they're not explicitly
initialized, are implicitly initialized to 0 with the appropriate type
(0 for integers, 0.0 for floating-point, NULL (not Null) for pointers,
applied recursively to struct and union members and array elements).
This applies to objects declared outside any function, and to objects
declared within a function with the "static" keyword.

Objects with automatic storage duration, if they're not explicitly
initialized, are not implicitly initialized. *Their initial values
will be garbage.
I wrote the above.
I learned something new today.
When you post a followup, please leave the attribution lines (such as
the "rt*******@gmail.com writes:" line above) in place. Quoting
someone else's words without giving them credit is considered rude.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 8 '08 #11

P: n/a
rt*******@gmail.com wrote:
On Oct 8, 3:38 pm, rtillm...@gmail.com wrote:
>>For extra credit and another approach to the problem, study the
sscanf function and consider how you might use a "%2x" specifier.
You mean something like this:
for (i=0, j=0; i<76; i++, j+=2){
sscanf(&temp[j], "%2x", &output[i]);
printf("%02x ", output[i]);
}

Thank you to everyone for your help.

The compiler threw a:
warning: format '%2x' expects type 'unsigned int *', but argument 3
has type 'unsigned int'
I find it difficult to believe that the code you've shown
could produce this error message. Are you sure this is your
actual code?
so I did the following:
sscanf(&temp[j], "%2x", (unsigned int*)&output[i]);

It silences the compiler and the output is the same but I wanted to
post to make sure this was the right way to handle the warning.

So is this right?
No. Or, "almost certainly not." You've been told at least twice
that using a cast to silence a compiler complaint is usually wrong,
so the fact that you persist in doing so suggests an unwillingness to
pay attention to the advice you ask for -- which in turn makes this
advisor wonder whether he's just wasting his time ...

To give a "for certain" answer, though, we need to see that
actual, complete code and not paraphrased snippets. And if you want
to show us compiler messages, please make sure they're rendered
accurately.

--
Er*********@sun.com
Oct 8 '08 #12

P: n/a
The compiler threw a:
warning: format '%2x' expects type 'unsigned int *', but argument 3
has type 'unsigned int'

I find it difficult to believe that the code you've shown
could produce this error message. Are you sure this is your
actual code?
It did and still does.
so I did the following:
sscanf(&temp[j], "%2x", (unsigned int*)&output[i]);
It silences the compiler and the output is the same but I wanted to
post to make sure this was the right way to handle the warning.
So is this right?

No. Or, "almost certainly not." You've been told at least twice
that using a cast to silence a compiler complaint is usually wrong,
so the fact that you persist in doing so suggests an unwillingness to
pay attention to the advice you ask for -- which in turn makes this
advisor wonder whether he's just wasting his time ...
This is why I asked.
To give a "for certain" answer, though, we need to see that
actual, complete code and not paraphrased snippets. And if you want
to show us compiler messages, please make sure they're rendered
accurately.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
const char temp[] =
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3000000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3";

unsigned char output[100];
int i,j;

for (i=0, j=0; i<100; i++, j+=2){
sscanf(&temp[j], "%2x", &output[i]);
printf("%02x ", output[i]);
if ((i+1) % 26 == 0) putchar('\n');
}
printf("\n");
return 0;
}

# gcc -Wall test.c -o test
test.c: In function 'main':
test.c:14: warning: format '%2x' expects type 'unsigned int *', but
argument 3 has type 'unsigned char *'

# ./test
2b 00 00 20 30 32 57 7e f6 a7 32 56 29 02 4b 0b 0a 0a bc 0b 75 39 20
40 bc 3c
1a 2b e4 b7 d9 31 29 f3 f1 de 7b 2a 92 00 00 b7 3a ed c3 f2 47 83 9c
c3 00 00
00 20 30 32 57 7e f6 a7 32 56 29 02 4b 0b 0a 0a bc 0b 75 39 20 40 bc
3c 1a 2b
e4 b7 d9 31 29 f3 f1 de 7b 2a 92 00 00 b7 3a ed c3 f2 47 83 9c c3
Oct 8 '08 #13

P: n/a
rt*******@gmail.com wrote:
>>The compiler threw a:
warning: format '%2x' expects type 'unsigned int *', but argument 3
has type 'unsigned int'
^^^ (see below)
> I find it difficult to believe that the code you've shown
could produce this error message. Are you sure this is your
actual code?

It did and still does.
Sorry; I should have considered the other possibility, which
turns out to be the right one. The code is as you showed it, but
the message was mis-reported.
>>so I did the following:
sscanf(&temp[j], "%2x", (unsigned int*)&output[i]);
It silences the compiler and the output is the same but I wanted to
post to make sure this was the right way to handle the warning.
So is this right?
No. Or, "almost certainly not." You've been told at least twice
that using a cast to silence a compiler complaint is usually wrong,
so the fact that you persist in doing so suggests an unwillingness to
pay attention to the advice you ask for -- which in turn makes this
advisor wonder whether he's just wasting his time ...

This is why I asked.
> To give a "for certain" answer, though, we need to see that
actual, complete code and not paraphrased snippets. And if you want
to show us compiler messages, please make sure they're rendered
accurately.

Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
const char temp[] =
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3000000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3";

unsigned char output[100];
int i,j;

for (i=0, j=0; i<100; i++, j+=2){
sscanf(&temp[j], "%2x", &output[i]);
Since output is an array of unsigned char, output[i] is one
of those unsigned char's, and &output[i] is a pointer to that
unsigned char. The "%2x" specifier scoops up two hexadecimal
digits, converts them to an unsigned int, and stores them in
the spot indicated by the corresponding argument. Does that
argument point to an unsigned int? No, as we've just seen, it
points to an unsigned char.
printf("%02x ", output[i]);
if ((i+1) % 26 == 0) putchar('\n');
}
printf("\n");
return 0;
}

# gcc -Wall test.c -o test
test.c: In function 'main':
test.c:14: warning: format '%2x' expects type 'unsigned int *', but
argument 3 has type 'unsigned char *'
^^^^^^ (see above)

When you "fixed" the problem by converting the pointer from
one type to another, you did not change the thing being pointed
at. You just said "Let's pretend this unsigned char is really
an unsigned int," and chanced the consequences. It's a lot like
saying "Let's pretend this umbrella is really a parachute" and
leaping out of the airplane. On this occasion it seems Mary
Poppins came to your aid, but you can't count on that ...

"If you lie to the compiler, it will get its revenge."
-- Henry Spencer

--
Er*********@sun.com
Oct 8 '08 #14

P: n/a
rtillm...@gmail.com wrote:
....
so I did the following:
sscanf(&temp[j], "%2x", (unsigned int*)&output[i]);
It silences the compiler and the output is the same but I wanted to
post to make sure this was the right way to handle the warning.
So is this right?
No. Or, "almost certainly not." You've been told at least twice
that using a cast to silence a compiler complaint is usually wrong,
so the fact that you persist in doing so suggests an unwillingness to
pay attention to the advice you ask for -- which in turn makes this
advisor wonder whether he's just wasting his time ...

This is why I asked.
That explains why you asked; it doesn't explain why you used the cast
after having been warned against using them.
To give a "for certain" answer, though, we need to see that
actual, complete code and not paraphrased snippets. And if you want
to show us compiler messages, please make sure they're rendered
accurately.

Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
const char temp[] =
"2b0000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3000000203032577ef6a7325629024b0b0a0abc0b75392040b c3c1a2be4b7d93129f3f1de7b2a920000b73aedc3f247839cc 3";

unsigned char output[100];
This should be declared as "unsigned int", not "unsigned char". Eric
suggested using unsigned char, and also suggested using sscanf() with
a "%2x" format specifier, but those two suggestions weren't mean to go
together.
int i,j;

for (i=0, j=0; i<100; i++, j+=2){
sscanf(&temp[j], "%2x", &output[i]);
printf("%02x ", output[i]);
if ((i+1) % 26 == 0) putchar('\n');
}
printf("\n");
return 0;
}

# gcc -Wall test.c -o test
test.c: In function 'main':
test.c:14: warning: format '%2x' expects type 'unsigned int *', but
argument 3 has type 'unsigned char *'
Oct 8 '08 #15

This discussion thread is closed

Replies have been disabled for this discussion.