views:

78

answers:

8

I don't use correctly the format specifiers in C. A few lines of code:

int main()
{
        char dest[]="stack";
        unsigned short val = 500;
        char c = 'a';

        char* final = (char*) malloc(strlen(dest) + 6);

        snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest); 

        printf("%s\n", final);
        return 0;
}

What I want is to copy at

final [0] = a random char final [1] = a random char final [2] and final [3] = the short array final [4] = another char ....

My problem is that i want to copy the two bytes of the short int to 2 bytes of the final array.

thanks.

+5  A: 

I'm confused - the problem is that you are saying strlen(dest)+6 which limits the length of the final string to 10 chars (plus a null terminator). If you say strlen(dest)+8 then there will be enough space for the full string.

Update

Even though a short may only be 2 bytes in size, when it is printed as a string each character will take up a byte. So that means it can require up to 5 bytes of space to write a short to a string, if you are writing a number above 10000.

Now, if you write the short to a string as a hexadecimal number using the %x format specifier, it will take up no more than 2 bytes.

Justin Ethier
I want to add 4 bytes (4 characters) and 2 more for a short integer, ie 6 characters
cateof
@cateof: But your short integer could use up to 5 characters (bytes) when formatted as a string. It's using 3 in this case (500).
Fred Larson
@cateof You forgot the NULL character, and when you convert your short to a string it becomes "500", which is three characters long and takes up three bytes. I believe the max short is 32767, so you should leave five bytes of space to be sure it'll fit
Michael Mrozek
It's unsigned, so the max is 65535. But it's still five characters.
John at CashCommons
+1  A: 

You need to allocate space for 13 characters - not 11. Don't forget the terminating NULL.

Alienfluid
+1  A: 

You loose one byte because you think the short variable takes 2 byte. But it takes three: one for each digit character ('5', '0', '0'). Also you need a '\0' terminator (+1 byte).

==> You need strlen(dest) + 8

Simon
a, ok. That is the problem. So i need to try it again.I want to create a char array that contains 1st byte = a random char2nd byte = a ramdom char3rd and 4th byte = a short int5th byte = a random char.So how can I copy the short int to a byte array?
cateof
Best to clarify your question to reflect those updated requirements.
jmanning2k
+1  A: 

Unsigned shorts can take up to 5 characters, right? (0 - 65535)

Seems like you'd need to allocate 5 characters for your unsigned short to cover all of the values.

Which would point to using this:

char* final = (char*) malloc(strlen(dest) + 10);
John at CashCommons
A: 

Use 8 instead of 6 on:

char* final = (char*) malloc(strlen(dest) + 6);

and

snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest);
pcent
+1  A: 

When formatted the number (500) takes up three spaces, not one. So your snsprintf should give the final length as strlen(dest)+5+3. Then also fix your malloc call to adjust. If you want to compute the strlen of the number, do that with a call like this strlen(itoa(val)). Also, cant forget the NULL at the end of dest, but I think strlen takes this into account, but I'm not for sure.

zdav
+1  A: 

Simple answer is you only allocated enough space for the strlen(dest) + 6 characters when in all reality it looks like you're going to have 8 extra characters... since you have 2 chars + 3 chars in your number + 2 chars after + dest (5 chars) = 13 char when you allocated 11 chars.

Ryan Zauber
A: 

Seems like the primary misunderstanding is that a "2-byte" short can't be represented on-screen as 2 1-byte characters.

First, leave enough room:

char* final = (char*) malloc(strlen(dest) + 9);

The entire range of possible values for a 1-byte character are not printable. If you want to display this on screen and be readable, you'll have to encode the 2-byte short as 4 hex bytes, such as:

## as hex, 4 characters
snprintf(final, sizeof(final), "%c%c%4x%c%c%s", c, c, val, c, c, dest);

If you are writing this to a file, that's OK, and you might try the following:

## print raw bytes, upper byte, then lower byte.
snprintf(final, sizeof(final), "%c%c%c%c%c%c%s", c, c, ((val<<8)&0xFF), ((val>>8)&0xFF), c, c, dest); 

But that won't make sense to a human looking at it, and is sensitive to endianness. I'd strongly recommend against it.

jmanning2k
Another caveat - the raw bytes snprintf statement only works for an *unsigned* short int.
jmanning2k