Convert hash to 4 hex numbers - c

I would like to convert my MD5 hash to 4 hex numbers. What's wrong in my code?
//hash = 8ce4b16b22b58894aa86c421e8759df3
char *hash = argv[1];
unsigned int parts[4];
sscanf(&hash[0], "%x", &parts[0]);
sscanf(&hash[8], "%x", &parts[1]);
sscanf(&hash[16], "%x", &parts[2]);
sscanf(&hash[24], "%x", &parts[3]);
printf("Part[0]: %x\n", parts[0]);
printf("Part[1]: %x\n", parts[1]);
printf("Part[2]: %x\n", parts[2]);
printf("Part[3]: %x\n", parts[3]);

In your code, you wanted but forgot to limit the input for the HEX value to 8 (in characters). You need to use the field width specifier with the format specifier. You will need something like
sscanf(&hash[0], "%8x", &parts[0]);
sscanf(&hash[8], "%8x", &parts[1]);
sscanf(&hash[16], "%8x", &parts[2]);
sscanf(&hash[24], "%8x", &parts[3]);

In your code, you are trying to tell sscanf() where to start parsing the string (stored in the variable named "hash"), but you aren't telling sscanf() where it should stop parsing it. Try inserting whitespace characters into "hash" where you want the 4 numbers to be divided, first, and then your code may work. Also, I would write "&(hash[0])" instead of "&hash[0]" because I don't want to clutter my memory banks with trivia such as the operator precedence rules for C - easier just to use parentheses to force what I want.

Related

sscanf not reading numbers

A newbie in C is trying to extract two numbers from a string using sscanf(). The numbers shall be parsed from strings formatted like "7-12", which should result in firstNode = 7and secondNode = 12. So I want to get the numbers, the minus sign can be understood as a number seperator. My current implementation is similar to the example I found on this SO answer:
void extractEdge(char *string) {
int firstNode = 123;
int secondNode = 123;
sscanf(string, "%*[^0123456789]%u%*[^0123456789]%u", &firstNode, &secondNode);
printf("Edge parsing results: Arguments are %s, %d, %d", string, firstNode, secondNode);
}
But if I execute the code above, there always is retourned the inital value 123 for both ints. Note that the output of string gives the correct input String, so I think an invalid string can't be a probable cause for this problem.
Any ideas why the code is not working? Thanks in advance for your help.
%*[^0123456789] requires one or more non-digit character, but the first character of you input 7-12 is a digit. This makes sscanf() stop there and read nothing.
Remove that and use "%d%*[^0123456789]%d" as format specifier to deal with 7-12.
Also note that correct format specifier for reading decimal int is %d, not %u. %u is for reading unsigned int.

error when printing special characters in C. The problem is %c vs %s

I'm starting with C, I have found a little difference between %c and %s, when must print special characters. I dont know if I'm doing something wrong, or it's a C limitation:
unsigned char str1[]="á";
printf("str1 c (%c)\n", str1[0]);
printf("str1 s (%s)\n", &str1[0]);
unsigned char str2[]="áéíóúñ";
printf("str2 s (%s)\n", str2);
And the output is:
str1 c ( )
str1 s (á)
str2 s (áéíóúñ)
In conclusion: when I try write special characters with %c, I cannot see it.
The %c format string for printf causes the corresponding argument to be converted to and interpreted as an unsigned char. An unsigned char is 1 byte long. One byte from your non-ASCII string does not necessarily correspond to anything you would recognize as a character.
It is likely that your editor, which you used to place some representation of those strings into your source code, encodes the two strings with some Unicode encoding scheme. This SO answer has some information to get you started on dealing with Unicode in C.
The reason things work fine with the %s formatting string is that printf will just start dumping out bytes until it hits the null byte terminator. Your output terminal is probably set to the same encoding scheme as your editor, so it's able to correctly interpret those bytes the way you intended.
Ok, now I understand it.
If I write:
unsigned char str3[]="a";
printf("%d\n", strlen((char *)str3));
The output is:
1
But I write:
unsigned char str1[]="á";
printf("%d\n", strlen((char *)str1));
The output is:
2
I understood that the character sizes can be 1, or 2 if are special characters , no?

Changing char* string in a C loop

I am trying to change a string within a loop to be able to save my images with a changing variable. Code snippet is as follows:
for (frames=1; frames<=10; frames++)
{
char* Filename = "NEWIMAGE";
int Save_Img = is_SaveImageMemEx (hCam, Filename, pMem, memID,
IS_IMG_PNG, 100);
printf("Status Save %d\n",Save_Img);
}
What I want to do is put a variable that changes with the loop counter inside Filename so my saved file changes name with every iteration.
Any help would be great.
Create a file name string with sprintf and use the %d format conversion specifier for an int:
char filename[32];
sprintf(filename, "NEWIMAGE-%d", frames);
sprintf works just like printf, but "prints" to a string instead of stdout.
If you declared frames as an unsigned int, use %u. If it is a size_t use %zu. For details see your friendly printf manual page, which will tell you how you can for example zero pad the number.
Be sure that the character array you write to is large enough to hold the longest output plus an extra '\0' character. In your particular case NEWIMAGE-10 + 1 means 11 + 1 = 12 characters is enough, but 32 is future-proof for some time.
If you want to program like a pro, look at the snprintf and asnprintf functions, which can limit or allocate the memory written to, respectively.
You can use sprintf to create a formatting string:
char Filename[50];
sprintf(Filename, "NEWIMAGE%d", frames);

why i have exc_bad_access doing cast?

i am programming in C and i have a problem while casting an int into a char.
I am using my mac with Xcode to program c.
The code is:
int main(){
int t = 2;
printf("test %s\n", (char)t); //EXC_BAD_ACCESS
return 0;
}
I tried all I found in many post, I really don't know what is going on... any suggestion?
Please include the goal of your code in your question not in a comment below.
If you want the output
test 2
your have to change %s to %d
printf("test %d\n", t);
I guess you got the wrong idea about the %s. It does not tell the printf that you want to have the int as string, it does tell printf that the parameter is a string! It is obviously not, so you got the exception.
if you use %c you tell the printf function that you want to output your number as character from your current ASCII table. For example 65 is 'A'.
If you have a concatenation situation like
strcpy(str_buscar, "controlID='");
strcat(str_buscar, (char) t);
strcat(str_buscar, "'");
you need itoa instead of the cast:
strcat(str_buscar, (char) t);
you need the follow:
char buffer[32]; // enough space for a "number as string"
itoa(t,buffer,10);
strcat(str_buscar, buffer);
a (IMHO) shortcut is to "print" to a buffer with sprintf
sprintf(str_buscar,"controlID='%d'",t);
instead of printing to a console sprintf prints into the given buffer. Make shure that your buffer str_buscar is big enough.
The %s format specifier represents a string, not an individual character. Printf thinks that the number 2 you're passing it is a string's address. It tries to access the memory address 2 and fails, because that address doesn't exist.
If you want to print a character, you'll want the %c specifier. This tells printf to print the character whose ASCII code is 2. The ASCII character number 2 is, according to the ASCII table, a control character that cannot be printed, which is why you're getting strange output.
If you actually want to print the character '2' (which has a different code, 50), you will want to use something like:
printf("test: %c", (char)('0' + c));
This example leverages the fact that all ASCII characters have consecutive codes, starting with 48 ('0'). This way, if you wanted to print the digit 0, you'd end up printing the '0' character (ASCII code 48 = 48 + 0). If you want to print the digit 2, you'll end up printing the '2' character (50 = 48 + 2).
This way, however, is a bit clunky and fails when encountering numbers larger than 9 (i.e. it only works with digits). The easier way consists of no longer working with characters at all and, instead, using the '%d' specifier (used for printing whole number):
int t = 0;
printf("test: %d", t);

memcpy() to copy integer value to char buffer

I am trying to copy the memory value of int into the char buffer. The code looks like below,
#define CPYINT(a, b) memcpy(a, &b, 4)
............
char str1[4];
int i = 1;
CPYINT(str1, i);
printf("%s",s);
...........
When I print str1 it’s blank. Please clarify.
You are copying the byte representation of an integer into a char array. You then ask printf to interpret this array as a null terminating string : str1[0] being zero, you are essentially printing an empty string (I'm skipping the endianness talk here).
What did you expect ? Obviously, if you wanted to print a textual representation of the integer i, you should use printf("%d", i).
try
printf("%02X %02X %02X %02X\n", str1[0], str1[1], str1[2], str1[3]);
instead.
The binary representation of the integer 1, probably contains leading NULs, and so your current printf statement terminates earlier than you want.
What is your intention here? Right now you are putting arbitrary byte values into the char array, but then interpreting them as a string, as it happens the first byte is probably a zero (null) and hence your print nothing, but in all probability many of the characters will be unprintable, so printf is the wrong tool to use to check if the copy worked.
So, either: loop through the array and print the numeric value of each byte, %0xd might be useful for that or if your intention is actually to create a string representation of the int then you'll need a larger buffer, and space for a null terminator.
Maybe you need convert intger to char* in that way tou can use itoa function
link text

Resources