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

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -