Advertisement
Robert_l

Untitled

Nov 18th, 2020
434
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.56 KB | None | 0 0
  1. #include <string.h>
  2. #include <stdarg.h>
  3. #include <math.h>
  4.  
  5. #include <iostream>
  6. #include <sstream>
  7. #include <fstream>
  8. #include <iterator>
  9. #include <vector>
  10. #include <string>
  11. #include <algorithm>
  12.  
  13. static inline char _is_digit(char ch)
  14. {
  15.     return (ch >= '0') && (ch <= '9');
  16. }
  17.  
  18. static uint8_t getNum(char **format)
  19. {
  20.     uint8_t ret = 0;
  21.     if (_is_digit(**format))
  22.     {
  23.         //get max lenght
  24.         ret = (**format) - '0';
  25.         (*format)++;
  26.         if (_is_digit(**format))
  27.         {
  28.             //get max lenght
  29.             ret = ret * 10 + ((**format) - '0');
  30.             (*format)++;
  31.         }
  32.     }
  33.     return ret;
  34. }
  35.  
  36. int _printFloat(char *buff, uint8_t bufLen, double val, uint8_t minLen, uint8_t precision)
  37. {
  38.     //debug
  39.  
  40.     uint8_t buffPtr = 0;
  41.     uint64_t digitPtr = 1;
  42.  
  43.     if (!isfinite(val))
  44.     {
  45.  
  46.         if (isnan(val))
  47.         {
  48.             if (bufLen--)
  49.                 *buff++ = 'N';
  50.             if (bufLen--)
  51.                 *buff++ = 'a';
  52.             if (bufLen--)
  53.                 *buff++ = 'N';
  54.         }
  55.         else if (isinf(val))
  56.         {
  57.             if (bufLen--)
  58.                 *buff++ = 'I';
  59.             if (bufLen--)
  60.                 *buff++ = 'n';
  61.             if (bufLen--)
  62.                 *buff++ = 'f';
  63.         }
  64.         int8_t lenTmp = minLen - 3;
  65.         minLen = lenTmp > 0 ? lenTmp : 0;
  66.         while (buffPtr < bufLen && minLen > 0)
  67.         {
  68.             if (minLen)
  69.                 minLen--;
  70.             buff[buffPtr++] = ' ';
  71.         }
  72.         return buffPtr;
  73.     }
  74.     if (val < 0)
  75.     {
  76.         val = -val;
  77.         if (minLen)
  78.             minLen--;
  79.         if (buffPtr < bufLen)
  80.         {
  81.  
  82.             buff[buffPtr++] = '-';
  83.         }
  84.     }
  85.  
  86.     while (val >= 10)
  87.     {
  88.         val /= 10;
  89.         digitPtr++;
  90.     }
  91.     if (precision > 32)
  92.         precision = 4;
  93.  
  94.     while (buffPtr < bufLen)
  95.     {
  96.         uint8_t digit;
  97.         if (digitPtr > 1)
  98.         {
  99.             digit = val + 0.5; //rand
  100.             buff[buffPtr++] = digit + '0';
  101.             digitPtr--;
  102.             val -= digit;
  103.             val *= 10;
  104.             if (minLen)
  105.                 minLen--;
  106.         }
  107.         else if (digitPtr == 1)
  108.         {
  109.             digit = val + 0.5;
  110.             buff[buffPtr++] = digit + '0';
  111.             val -= digit;
  112.             val *= 10;
  113.             digitPtr = 0;
  114.             if (minLen)
  115.                 minLen--;
  116.             if (precision == 0)
  117.                 return buffPtr;
  118.             if (buffPtr < bufLen)
  119.             {
  120.                 bufLen--;
  121.                 if (minLen)
  122.                     minLen--;
  123.                 buff[buffPtr++] = '.';
  124.             }
  125.         }
  126.         else
  127.         {
  128.             if (precision-- == 0)
  129.             {
  130.                 while (buffPtr < bufLen && minLen > 0)
  131.                 {
  132.                     if (minLen)
  133.                         minLen--;
  134.                     buff[buffPtr++] = ' ';
  135.                 }
  136.                 return buffPtr;
  137.             }
  138.             digit = val + 0.5;
  139.             buff[buffPtr++] = digit + '0';
  140.             val -= digit;
  141.             val *= 10;
  142.             //buff[buffPtr++] = (char) val + '0';
  143.             if (minLen)
  144.                 minLen--;
  145.         }
  146.     }
  147.     return buffPtr;
  148. }
  149. //put only i32/u32/ double
  150. void sprintf_simple(char *buff, int buffLen, char *format, ...)
  151. {
  152.     if (buff == 0 || format == 0 || buffLen < 2)
  153.         return;
  154.     uint16_t buffPtr = 0;
  155.     va_list argptr;
  156.     va_start(argptr, format);
  157.  
  158.     while (format)
  159.     {
  160.  
  161.         //if (buffPtr >= buffLen)break;
  162.  
  163.         if (*format == '%')
  164.         {
  165.             //char *bakcup = format;
  166.             if (*(format + 1) == '%')
  167.             {
  168.                 format += 2;
  169.                 if (buffPtr < buffLen - 1)
  170.                 {
  171.                     buff[buffPtr++] = '%';
  172.                     continue;
  173.                 }
  174.                 else
  175.                 {
  176.                     buff[buffPtr - 2] = 0;
  177.                     break;
  178.                 }
  179.             }
  180.             //print float;
  181.  
  182.             unsigned char space = 0;
  183.             unsigned char precision = 0;
  184.             format++;
  185.             space = getNum(&format);
  186.             //format++;
  187.             if (*format == '.')
  188.             {
  189.                 //get prec
  190.                 format++;
  191.                 precision = getNum(&format);
  192.             }
  193.             if (*format == 'f')
  194.             {
  195.                 format++;
  196.                 buffPtr += _printFloat(&buff[buffPtr], buffLen - buffPtr, va_arg(argptr, double), space, precision);
  197.             }
  198.             else if (*format == 'i')
  199.             {
  200.                 format++;
  201.                 buffPtr += _printFloat(&buff[buffPtr], buffLen - buffPtr, (double)va_arg(argptr, int32_t), space, precision);
  202.             }
  203.             else if (*format == 'u')
  204.             {
  205.                 format++;
  206.                 buffPtr += _printFloat(&buff[buffPtr], buffLen - buffPtr, (double)va_arg(argptr, uint32_t), space, precision);
  207.             }
  208.             else
  209.             {
  210.                 //error
  211.                 if (buffPtr < buffLen - 4)
  212.                 {
  213.                     buff[buffPtr++] = '#';
  214.                     buff[buffPtr++] = 'E';
  215.                     buff[buffPtr++] = 'R';
  216.                     buff[buffPtr++] = '#';
  217.                 }
  218.                 else
  219.                 {
  220.                     break;
  221.                 }
  222.             }
  223.         }
  224.         else
  225.         {
  226.             if (buffPtr < buffLen)
  227.             {
  228.                 char tmp = *format++;
  229.                 buff[buffPtr++] = tmp;
  230.             }
  231.             else
  232.                 break;
  233.         }
  234.     }
  235.     if (buffPtr < buffLen)
  236.     {
  237.         buff[buffPtr] = 0;
  238.     }
  239.     else
  240.         buff[buffLen - 1] = 0;
  241.     va_end(argptr);
  242. }
  243.  
  244. #define buffSize 32
  245. void printfTest()
  246. {
  247.     using namespace std;
  248.  
  249.     char buff[buffSize];
  250.     float pi = 3.14159265359;
  251.     memset(buff, 0, 31);
  252.     sprintf_simple(buff, buffSize, "%8.1f_%4.2f_%.6f_", pi, pi * 10, pi * 100);
  253.     cout << buff << endl;
  254.     memset(buff, 0, 32);
  255.     sprintf_simple(buff, 30, "abc123.%%1.1%f&%4.2f&%.6f", pi, pi * 10, pi * 100);
  256.     cout << buff << endl;
  257.     memset(buff, 0, 32);
  258.     sprintf_simple(buff, 8, "%f %4.2f %.6f", pi, pi * 10, pi * 100);
  259.     cout << buff << endl;
  260.     memset(buff, 0, 32);
  261.     sprintf_simple(buff, 24, "%f %4.2f %.6f", pi / 100, pi / 10, pi / 100);
  262.     cout << buff << endl;
  263.     sprintf_simple(buff, 32, "%i %u %f", -123, 10000);
  264.     cout << buff << endl;
  265. }
  266.  
  267. int main()
  268. {
  269.     printfTest();
  270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement