how can i write binary bits into binary file in C? -
i trying implement huffman encoding in c. done tree construction , obtained codeword each symbol algorithm proceeds. stuck insertion of codewords binary files corresponding symbol. can suggest how codeword or binary bits can written binary file can obtain compressed file.
the codewords of variable length.
a function write , read these bits to/from file helpful.
this code have written
void create_compressed_file() { char str[20],ch,*str2,str1[10],str_arr[6],str3[10]; file *fp,*fp2,*fp3; int i,array[20],j=0; fp2=fopen("newfile.txt","r"); // contains original text file fp3=fopen("codeword.txt","r"); // contains symbol , codeword while(fscanf(fp2,"%s",&str)==1) { rewind(fp3); str2=strtok(str,"-"); while(str2!=null) { strcpy(str_arr,str2); printf("str2= %s ",str_arr); //str2 stores symbol(not char string) printf(" %s-",str2); while(fscanf(fp3,"%s",&str1)==1) { if(strcmp(str1,str_arr)==0) { fscanf(fp3,"%s",&str1); // extracted corresponding codeword(1s , 0s) of symbol , stored str1 printf("%s\n",str1); write_codeword_to_binaryfile(); // function want create incomplete , need help. } } str2=strtok(null,"-"); rewind(fp3); } printf("\nspace:"); strcpy(str_arr,"space"); while(fscanf(fp3,"%s",&str1)==1) { if(strcmp(str1,str_arr)==0) { fscanf(fp3,"\n%s",&str1); // extract codeword for(space)character printf("%s\n",str1); } } } fclose(fp2); fclose(fp3); }
codeword.txt:
is 0000 por 00010 plain 000110 0001110 0001111 ted 00100 text 00101 ly 0011000 near 0011001 pli 0011010 ap 0011011 ble 0011100 ta 0011101 0011110 sup 0011111 cryp 0100000 in 0100001 ra 0100010 tog 0100011 ting 0100100 tain 0100101 mands 0100110 com 0100111 mes 0101000 0101001 ge 0101010 sa 0101011 plain 0101100 phy 0101101 tried above code below dint write anything...the file size after execution 0 bytes: #include<stdio.h> #include<conio.h> #include<stdint.h> void write_codeword_to_binaryfile( const char *codeword, // codeword write, in ascii format file *file, // destination file uint8_t *buffer, int *fullness) { char c; // fullness = ; *buffer = 0; ( c = *codeword++; c != '\0'; c = *codeword++) // iterate { int bit = c - '0'; // convert ascii binary 0/1 *buffer |= bit << (7 - fullness); ++fullness; } fputc(*buffer, file); } int main() { file *fp; uint8_t *buffer=0; char *c="10101010"; char b = 0; int i; fp=fopen("myfile.bin","wb"); write_codeword_to_binaryfile( c,fp,buffer, 8); fclose(fp); getch(); }
first of all, should open file in binary mode:
fp = fopen("myfile", "wb"); // "b" means "binary"
this must in windows, not necessary on other platforms (you don't need special differentiate platform; use "wb").
to write bits file, should use buffer - partially-filled byte. write buffer file when fills (contains 8 filled bits).
uint8_t buffer = 0;
you should use counter tracks how many bits filled.
int fullness = 0;
your function, writes file, should receive buffer , fullness. since change them, have send pointers:
void write_codeword_to_binaryfile( const char *codeword, // codeword write, in ascii format file *file, // destination file uint8_t *buffer, int *fullness) { (char c = *codeword++; c != '\0'; c = codeword++) // iterate { int bit = c - '0'; // convert ascii binary 0/1 ... } }
there 2 ways arrange bits in byte - little-endian (first bit least-significant bit) or big-endian (first bit most-significant bit). customary way use big-endian ordering.
so if buffer has number of bits filled, how fill next bit? following example shows buffer 5 bits filled:
011011... ^ next bit fill (its position, starting left, 2)
as can see example, position of next bit 7 - fullness
. so, each bit, following:
*buffer |= bit << (7 - *fullness); ++fullness;
see how set, clear , toggle single bit in c/c++? more info.
when buffer full (fullness
equal 8), write file:
fputc(*buffer, file); *fullness = 0; *buffer = 0;
you should "flush" buffer (i.e. write file) when finished encoding message:
if (*fullness > 0) fputc(*buffer, file);
by way, happens @ end of message common non-trivial problem bit-level encoders. should think point of view of decoder: need understand how many bits should decode in last byte of file. there several solutions this:
- after encoding message, encode additional
1
bit, , 0 bits until buffer full. decoder need decode 0 bits ,1
bit in reverse. used mpeg. - write length of message, in bits, in file's header. simplest solution, although requires updating file's beginning after finishing encoding.
- have special codeword "end of message" (also used)
Comments
Post a Comment