Ints as strings, malloc

T

togipete

I'm working on a huffman encoding program right now for my C class - I
got the frequency and encoding table working just fine but am having
problems writing the output. The output format is: int representing the
number of chars in the freq table (4 bytes), followed by the first char
in the freq table (1 byte) followed by its count (int, 4 bytes) for
each element in the freq table. File output is supposed to be done
using unbuffered IO

char *tchar; /* buffer to hold totalchars as a string to write */
int totalchars;
....
tchar = (char *)malloc( sizeof(int) );
sprintf(tchar, "%d", totalchars);
write(outfd,tchar,sizeof(int));

This is just for the first part of the file with the total number of
chars but the problem seems to be the same in the rest of the output...
say my totalchars was 5, when I view my encoded file im expecting to
see a 05 00 00 00 to start the file, but I get some random garbage like
35 00 1a c0 (I'm still learning the language, but it looks as though
the rest of string has old garbage in it still). What would be the best
way to initialize the string to 0s or what would be a better solution?
 
N

Nick Keighley

togipete said:
I'm working on a huffman encoding program right now for my C class - I
got the frequency and encoding table working just fine but am having
problems writing the output. The output format is: int representing the
number of chars in the freq table (4 bytes), followed by the first char
in the freq table (1 byte) followed by its count (int, 4 bytes) for
each element in the freq table. File output is supposed to be done
using unbuffered IO

int table_size;
char value; }
int count; } repeat
char *tchar; /* buffer to hold totalchars as a string to write */
int totalchars;
...
tchar = (char *)malloc( sizeof(int) );

don't cast the return value of malloc. Always check the return value
of malloc()
are you certain that the representaion of totalchars will always fit
into three bytes? You'll never have 1000 or more characters? In other
words "why sizeof(int)"? If you know 4 bytes is enough why use
malloc()?
sprintf(tchar, "%d", totalchars);
write(outfd,tchar,sizeof(int));

write() is non-standard. I'll assume you are using it correctly.
This is just for the first part of the file with the total number of
chars but the problem seems to be the same in the rest of the output...

It would make life easier if you were to post a *short* *compilable*
program that illustrated your problem. Explaining what you see, what
you expect and why you have a problem with the difference.

say my totalchars was 5, when I view my encoded file im expecting to
see a 05 00 00 00 to start the file, but I get some random garbage like
35 00 1a c0

how do you know? Did you use some sort of hex dump utility to view
the output? Note 35 is the hexadecimal for the ASCII encoding of the
character '5'. After the sprintf() your buffer will contain
5<nul><garbage><garbage>

what do you expect it to contain?
(I'm still learning the language, but it looks as though
the rest of string has old garbage in it still). What would be the best
way to initialize the string to 0s or what would be a better solution?

I don't know what you are trying to do. Do you want the output to be
readable text or binary? If you want binary don't use sprintf().
For instance this writes the first four bytes in binary:-

void dump_output (FILE* f, const unsigned char* buff)
{
if (fwrite(buff, sizeof(int), 1, f) != sizeof(int))
fprintf (stderr, "error writing totalchars\n");
}

code is untested.
 
M

Mac

int table_size;
char value; }
int count; } repeat


don't cast the return value of malloc. Always check the return value
of malloc()
are you certain that the representaion of totalchars will always fit
into three bytes? You'll never have 1000 or more characters? In other
words "why sizeof(int)"? If you know 4 bytes is enough why use
malloc()?


write() is non-standard. I'll assume you are using it correctly.


It would make life easier if you were to post a *short* *compilable*
program that illustrated your problem. Explaining what you see, what
you expect and why you have a problem with the difference.



how do you know? Did you use some sort of hex dump utility to view
the output? Note 35 is the hexadecimal for the ASCII encoding of the
character '5'. After the sprintf() your buffer will contain
5<nul><garbage><garbage>

what do you expect it to contain?


I don't know what you are trying to do. Do you want the output to be
readable text or binary? If you want binary don't use sprintf().
For instance this writes the first four bytes in binary:-

void dump_output (FILE* f, const unsigned char* buff)
{
if (fwrite(buff, sizeof(int), 1, f) != sizeof(int))
fprintf (stderr, "error writing totalchars\n");
}

code is untested.

fwrite() returns the number of elements written, not the number of bytes
or chars. So the comparison should be with 1, not sizeof (int):

if (fwrite(buff, sizeof(int), 1, f) != 1)

Also, this is really badly structured. I would vote for something more
like this (also untested):

int dump_int (FILE* f, int i)
{
if (fwrite(&i, sizeof i, 1, f) != 1)
{
fprintf (stderr, "error writing int\n");
return EXIT_FAILURE;
}
else return EXIT_SUCCESS;
}

--Mac
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,170
Messages
2,570,925
Members
47,466
Latest member
DrusillaYa

Latest Threads

Top