Let's first directly address your bug: In your code you attempt to add the next byte to your string with:
[newString appendFormat:@"%c", (char)value];
Your problem is that %c
produces nothing if the character is a null, so you are appending an empty string and as you found end up with a string with a single byte in it.
You can fix your code by testing for the null and appending a string containing a single null:
if (value == 0)
[newString appendString:@"\0"]; // append a single null
else
[newString appendFormat:@"%c", (char)value];
Second, is this the way to do this?
Other answers have shown you other algorithms, they might be more efficient than yours as they only convert to a C-String once rather than repeatedly extract substrings and convert each one individually.
If and only if performance is a real issue for you you might wish to consider such C-based solutions. You clearly know how to use scanf
, but in such a simple case as this you might want to look at digittoint
and do the conversion of two hex digits to an integer yourself (value of first * 16 + value of second).
Conversely if you'd like to avoid C and scanf
look at NSScanner
and scanHexInt
/scanHexLongLong
- if your strings are never longer than 16 hex digits you can convert the whole string in one go and then produce an NSString
from the bytes of the resultant unsigned 64-bit integer.
HTH