c - Minimal implementation of sprintf or printf -


i'm working on embedded dsp speed crucial, , memory short.

at moment, sprintf uses resources of function in code. use format simple text: %d, %e, %f, %s, nothing precision or exotic manipulations.

how can implement basic sprintf or printf function more suitable usage?

this 1 assumes existence of itoa convert int character representation, , fputs write out string wherever want go.

the floating point output non-conforming in @ least 1 respect: makes no attempt @ rounding correctly, standard requires, if have have (for example) value of 1.234 internally stored 1.2399999774, it'll printed out 1.2399 instead of 1.2340. saves quite bit of work, , remains sufficient typical purposes.

this supports %c , %x in addition conversions asked about, they're pretty trivial remove if want rid of them (and doing save little memory).

#include <stdarg.h> #include <stdio.h> #include <string.h> #include <windows.h>  static void ftoa_fixed(char *buffer, double value); static void ftoa_sci(char *buffer, double value);  int my_vfprintf(file *file, char const *fmt, va_list arg) {      int int_temp;     char char_temp;     char *string_temp;     double double_temp;      char ch;     int length = 0;      char buffer[512];      while ( ch = *fmt++) {         if ( '%' == ch ) {             switch (ch = *fmt++) {                 /* %% - print out single %    */                 case '%':                     fputc('%', file);                     length++;                     break;                  /* %c: print out character    */                 case 'c':                     char_temp = va_arg(arg, int);                     fputc(char_temp, file);                     length++;                     break;                  /* %s: print out string       */                 case 's':                     string_temp = va_arg(arg, char *);                     fputs(string_temp, file);                     length += strlen(string_temp);                     break;                  /* %d: print out int         */                 case 'd':                     int_temp = va_arg(arg, int);                     itoa(int_temp, buffer, 10);                     fputs(buffer, file);                     length += strlen(buffer);                     break;                  /* %x: print out int in hex  */                 case 'x':                     int_temp = va_arg(arg, int);                     itoa(int_temp, buffer, 16);                     fputs(buffer, file);                     length += strlen(buffer);                     break;                  case 'f':                     double_temp = va_arg(arg, double);                     ftoa_fixed(buffer, double_temp);                     fputs(buffer, file);                     length += strlen(buffer);                     break;                  case 'e':                     double_temp = va_arg(arg, double);                     ftoa_sci(buffer, double_temp);                     fputs(buffer, file);                     length += strlen(buffer);                     break;             }         }         else {             putc(ch, file);             length++;         }     }     return length; }  int normalize(double *val) {     int exponent = 0;     double value = *val;      while (value >= 1.0) {         value /= 10.0;         ++exponent;     }      while (value < 0.1) {         value *= 10.0;         --exponent;     }     *val = value;     return exponent; }  static void ftoa_fixed(char *buffer, double value) {       /* carry out fixed conversion of double value string, precision of 5 decimal digits.       * values absolute values less 0.000001 rounded 0.0      * note: blindly assumes buffer large enough hold largest possible result.      * largest value expect ieee 754 double precision real, maximum magnitude of approximately      * e+308. c standard requires implementation allow single conversion produce 512       * characters, that's expect buffer size.           */      int exponent = 0;     int places = 0;     static const int width = 4;      if (value == 0.0) {         buffer[0] = '0';         buffer[1] = '\0';         return;     }               if (value < 0.0) {         *buffer++ = '-';         value = -value;     }      exponent = normalize(&value);      while (exponent > 0) {         int digit = value * 10;         *buffer++ = digit + '0';         value = value * 10 - digit;         ++places;         --exponent;     }      if (places == 0)         *buffer++ = '0';      *buffer++ = '.';      while (exponent < 0 && places < width) {         *buffer++ = '0';         --exponent;         ++places;     }      while (places < width) {         int digit = value * 10.0;         *buffer++ = digit + '0';         value = value * 10.0 - digit;         ++places;     }     *buffer = '\0'; }  void ftoa_sci(char *buffer, double value) {     int exponent = 0;     int places = 0;     static const int width = 4;      if (value == 0.0) {         buffer[0] = '0';         buffer[1] = '\0';         return;     }      if (value < 0.0) {         *buffer++ = '-';         value = -value;     }      exponent = normalize(&value);      int digit = value * 10.0;     *buffer++ = digit + '0';     value = value * 10.0 - digit;     --exponent;      *buffer++ = '.';      (int = 0; < width; i++) {         int digit = value * 10.0;         *buffer++ = digit + '0';         value = value * 10.0 - digit;     }      *buffer++ = 'e';     itoa(exponent, buffer, 10); }  int my_printf(char const *fmt, ...) {     va_list arg;     int length;      va_start(arg, fmt);     length = my_vfprintf(stdout, fmt, arg);     va_end(arg);     return length; }  int my_fprintf(file *file, char const *fmt, ...) {     va_list arg;     int length;      va_start(arg, fmt);     length = my_vfprintf(file, fmt, arg);     va_end(arg);     return length; }   #ifdef test   int main() {      float floats[] = { 0.0, 1.234e-10, 1.234e+10, -1.234e-10, -1.234e-10 };      my_printf("%s, %d, %x\n", "some string", 1, 0x1234);      (int = 0; < sizeof(floats) / sizeof(floats[0]); i++)         my_printf("%f, %e\n", floats[i], floats[i]);      return 0; }  #endif 

Comments

Popular posts from this blog

.htaccess - First slash is removed after domain when entering a webpage in the browser -

Automatically create pages in phpfox -

c# - Farseer ContactListener is not working -