Advertisement
2607

s21_string.c

Dec 4th, 2021
2,617
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 34.10 KB | None | 0 0
  1. #include "s21_string.h"
  2. #include <float.h>
  3. #include <math.h>
  4. #include <stdarg.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <wchar.h>
  8.  
  9.  
  10.  
  11. s21_size_t s21_strlen(const char *str) {
  12.     return (*str) ? s21_strlen(++str) + 1 : 0;
  13. }
  14.  
  15. void *s21_memchr(const void *str, int c, s21_size_t n) {
  16.     char *ch = s21_NULL;
  17.     for (s21_size_t i = 0; i < n; i++) {
  18.         if (*((char *)str + i) == c) {
  19.             ch = (char *)str + i;
  20.             break;
  21.         }
  22.     }
  23.     return ch;
  24. }
  25.  
  26. int s21_memcmp(const void *str1, const void *str2, s21_size_t n) {
  27.     int ch = 0;
  28.     for (s21_size_t i = 0; i < n; i++) {
  29.         if (*((char *)str1 + i) != *((char *)str2 + i)) {
  30.             ch = *((char *)str1 + i) - *((char *)str2 + i);
  31.             break;
  32.         }
  33.     }
  34.     return ch;
  35. }
  36.  
  37. void *s21_memcpy(void *dest, const void *src, s21_size_t n) {
  38.     for (s21_size_t i = 0; i < n; i++) {
  39.         *((char *)dest + i) = *((char *)src + i);
  40.     }
  41.     return dest;
  42. }
  43.  
  44. void *s21_memmove(void *dest, const void *src, s21_size_t n) {
  45.     char *buff = (char *)calloc(n, sizeof(char));
  46.     s21_memcpy(buff, src, n);
  47.     s21_memcpy(dest, buff, n);
  48.     free(buff);
  49.     return dest;
  50. }
  51.  
  52. void *s21_memset(void *str, int c, s21_size_t n) {
  53.     for (s21_size_t i = 0; i < n; i++) {
  54.         *((char *)str + i) = c;
  55.     }
  56.     return str;
  57. }
  58.  
  59. char *s21_strcat(char *dest, const char *src) {
  60.     s21_size_t size = s21_strlen(dest);
  61.     int i = 0;
  62.     for (; *(src + i) != '\0'; i++) {
  63.         *(dest + size + i) = *(src + i);
  64.     }
  65.     *(dest + size + i) = '\0';
  66.     return dest;
  67. }
  68.  
  69. char *s21_strncat(char *dest, const char *src, s21_size_t n) {
  70.     char *start = dest;
  71.     dest += s21_strlen(dest);
  72.     for (; (n != 0 && *src != '\0'); n--) {
  73.         *dest = *src;
  74.         src++;
  75.         dest++;
  76.     }
  77.     if (*(dest - 1) != '\0') {
  78.         *dest = '\0';
  79.     }
  80.     return start;
  81. }
  82.  
  83. char *s21_strchr(const char *str, int c) {
  84.     char *result_adrr = s21_NULL;
  85.     s21_size_t i;
  86.     for (i = 0; i < s21_strlen(str); i++) {
  87.         if (*((char *)str + i) == c) {
  88.             result_adrr = (char *)str + i;
  89.             break;
  90.         } else {
  91.             result_adrr = 0;
  92.         }
  93.     }
  94.     return (result_adrr != 0) ? result_adrr : (char *)s21_NULL;
  95. }
  96.  
  97. int s21_strcmp(const char *str1, const char *str2) {
  98.     int result = 0;
  99.     for (int i = 0; *((char *)str1 + i) != '\0' || *((char *)str2 + i) != '\0'; i++) {
  100.         result = *(str1 + i) - *(str2 + i);
  101.         if (result != 0) {
  102.             break;
  103.         }
  104.     }
  105.     return (result);
  106. }
  107.  
  108. int s21_strncmp(const char *str1, const char *str2, s21_size_t n) {
  109.     int result = 0;
  110.     for (int i = 0; (*((char *)str1 + i) != '\0' || *((char *)str2 + i) != '\0') && i < (int)n; i++) {
  111.         result = *(str1 + i) - *(str2 + i);
  112.         if (result != 0) {
  113.             break;
  114.         }
  115.     }
  116.     return (result);
  117. }
  118.  
  119. char *s21_strcpy(char *dest, const char *src) {
  120.     char *r = dest;
  121.     while ((*dest++ = *src++)) {
  122.     }
  123.     return r;
  124. }
  125.  
  126. char *s21_strncpy(char *dest, const char *src, s21_size_t n) {
  127.     s21_size_t i = 0;
  128.     int size = s21_strlen(dest);
  129.     for (int j = 0; j < size; j++) {
  130.         *(dest + j) = 0;
  131.     }
  132.     do {
  133.         if (i < n) {
  134.             *(dest + i) = *(src + i);
  135.             i++;
  136.         } else {
  137.             break;
  138.         }
  139.     } while (*((char *)src + i) != '\0');
  140.     return (dest);
  141. }
  142.  
  143. s21_size_t s21_strcspn(const char *str1, const char *str2) {
  144.     s21_size_t i = 0;
  145.     while (i < s21_strlen(str1)) {
  146.         if (s21_memchr(str2, *(str1 + i), s21_strlen(str2)) == s21_NULL) {
  147.             i++;
  148.         } else {
  149.             break;
  150.         }
  151.     }
  152.     return (i);
  153. }
  154.  
  155. char *s21_strerror(int errnum) {
  156.     char *out = (char *)calloc(50, sizeof(char));
  157.     int err_p_max = 107;
  158.     #if MACOS == 1
  159.     err_p_max = 132;
  160.     #endif
  161.     #if LINUX == 1
  162.     err_p_max = 107;
  163.     #endif
  164.     if (errnum < 0 || errnum > err_p_max) {
  165.         #if MACOS == 1
  166.         s21_sprintf(out, "Unknown error: %d", errnum);
  167.         #endif
  168.         #if LINUX == 1
  169.         s21_sprintf(out, "No error information");
  170.         #endif
  171.     } else {
  172.          #if MACOS == 1
  173.         s21_sprintf(out, "%s", ErrorNames1[errnum]);
  174.          #endif
  175.          #if LINUX ==1
  176.         s21_sprintf(out, "%s", ErrorNames[errnum]);
  177.         #endif
  178.     }
  179.     out = (char *)realloc(out, s21_strlen(out));
  180.     return (out);
  181. }
  182.  
  183. char *s21_strpbrk(const char *str1, const char *str2) {
  184.     s21_size_t i = 0;
  185.     char *ch;
  186.     while (*(str1 + i) && s21_strchr(str2, *(str1 + i)) == s21_NULL) i++;
  187.     ch = *(str1 + i) ? (char *)(str1 + i) : s21_NULL;
  188.     return (ch);
  189. }
  190.  
  191. char *s21_strrchr(const char *str, int c) {
  192.     char *ch = s21_NULL;
  193.     for (int i = s21_strlen(str); i >= 0; i--)
  194.         if (str[i] == c) {
  195.             ch = (char *)str + i;
  196.             break;
  197.         }
  198.     return ch;
  199. }
  200.  
  201. s21_size_t s21_strspn(const char *str1, const char *str2) {
  202.     s21_size_t i, j;
  203.     for (i = 0; str1[i] != '\0'; i++) {
  204.         for (j = 0; str2[j] != str1[i]; j++) {
  205.             if (str2[j] == '\0')
  206.                 return i;
  207.         }
  208.     }
  209.     return i;
  210. }
  211.  
  212. char *s21_strstr(const char *haystack, const char *needle) {
  213.     int flag;
  214.  
  215.     for (int i = 0; haystack[i] != '\0'; i++) {
  216.         if (haystack[i] == needle[0])
  217.             flag = 0;
  218.         for (int j = 0; needle[j] != '\0'; j++) {
  219.             if (haystack[i + j] != needle[j]) {
  220.                 flag = 1;
  221.                 break;
  222.             }
  223.         }
  224.         if (flag == 0)
  225.             return (char *)haystack + i;
  226.     }
  227.     return s21_NULL;
  228. }
  229.  
  230. char *s21_strtok(char *str, const char *delim) {
  231.     static char *buffer;
  232.     char *token = s21_NULL;
  233.     if (str) {
  234.         buffer = str;
  235.         while (*buffer && s21_strchr(delim, *buffer)) {
  236.             *buffer++ = '\0';
  237.         }
  238.     }
  239.     if (buffer && *buffer) {
  240.         str = buffer;
  241.         while (*buffer && !s21_strchr(delim, *buffer)) {
  242.             ++buffer;
  243.         }
  244.         while (*buffer && s21_strchr(delim, *buffer)) {
  245.             *buffer++ = '\0';
  246.         }
  247.         token = str;
  248.     }
  249.     return token;
  250. }
  251.  
  252. void *s21_to_upper(const char *str) {
  253.     char *new_string = (char *)calloc(s21_strlen(str), sizeof(char));
  254.     if (str != s21_NULL) {
  255.         s21_strcpy(new_string, str);
  256.         s21_size_t i = 0;
  257.         for (; i < s21_strlen(new_string); i++) {
  258.             if (new_string[i] >= 97 && new_string[i] <= 122) {
  259.                 new_string[i] = new_string[i] - 32;
  260.             }
  261.         }
  262.     } else {
  263.         free(new_string);
  264.         new_string = s21_NULL;
  265.     }
  266.     return new_string;
  267. }
  268.  
  269. void *s21_to_lower(const char *str) {
  270.     char *new_string = (char *)calloc(s21_strlen(str), sizeof(char));
  271.     if (str != s21_NULL) {
  272.         s21_strcpy(new_string, str);
  273.         s21_size_t i = 0;
  274.         for (; i < s21_strlen(new_string); i++) {
  275.             if (new_string[i] >= 65 && new_string[i] <= 90) {
  276.                 new_string[i] = new_string[i] + 32;
  277.             }
  278.         }
  279.     } else {
  280.         free(new_string);
  281.         new_string = s21_NULL;
  282.     }
  283.     return new_string;
  284. }
  285.  
  286. void *s21_insert(const char *src, const char *str, s21_size_t start_index) {
  287.     char *new_string = s21_NULL;
  288.     if (src && str && s21_strlen(src) >= start_index) {
  289.         new_string = (char *)calloc((s21_strlen(src) + s21_strlen(str)), sizeof(char));
  290.         s21_strncpy(new_string, src, start_index);
  291.         new_string[start_index] = '\0';
  292.         s21_strcat(new_string, str);
  293.         s21_strcat(new_string, src + start_index);
  294.     }
  295.     return new_string;
  296. }
  297.  
  298. void clean_str(char *str, int size_str) {
  299.     if (size_str > 0) {
  300.         for (int j = 0; j < size_str; j++) {
  301.             *(str + j) = 0;
  302.         }
  303.     }
  304. }
  305.  
  306. int s21_sprintf(char *str, const char *format, ...) {
  307.     parcer_t spec[20];
  308.     char *res = (char *)calloc(1000, sizeof(char));
  309.     parcer(format, spec);
  310.     va_list temp;
  311.     va_start(temp, format);
  312.     int size_format = s21_strlen(format);
  313.     int i = 0;
  314.     for (int j = 0; j < size_format; j++) {
  315.         if (*(format + j) == '%' && spec[i].spec_pos == j) {
  316.             if (spec[i].width_arg_flag == 1) {
  317.                 spec[i].width = va_arg(temp, int);
  318.             }
  319.             if (spec[i].accur_arg_flag == 1) {
  320.                 spec[i].accur = va_arg(temp, int);
  321.             }
  322.             if (spec[i].specif == 'c') {
  323.                 check_ch(&(spec[i]), res, va_arg(temp, int));
  324.             } else if (spec[i].specif == 'd' || spec[i].specif == 'i' || spec[i].specif == 'u') {
  325.                 long int ld;
  326.                 short int sd;
  327.                 unsigned long int uld;
  328.                 unsigned short int usd;
  329.                 unsigned int ud;
  330.                 int d;
  331.  
  332.                 switch (spec[i].lenght) {
  333.                     case 'h': {
  334.                         if (spec[i].specif == 'u') {
  335.                             usd = va_arg(temp, unsigned int);
  336.                             ld = (long int)usd;
  337.                         } else {
  338.                             sd = va_arg(temp, int);
  339.                             ld = (long int)sd;
  340.                         }
  341.                         break;
  342.                     }
  343.                     case 'l': {
  344.                         if (spec->specif == 'u') {
  345.                             uld = (long int)va_arg(temp, unsigned long int);
  346.                             ld = (long int)uld;
  347.  
  348.                         } else {
  349.                             ld = va_arg(temp, long int);
  350.                         }
  351.                         break;
  352.                     }
  353.                     default: {
  354.                         if (spec->specif == 'u') {
  355.                             ud = (long int)va_arg(temp, unsigned int);
  356.                             ld = (long int)ud;
  357.  
  358.                         } else {
  359.                             d = (long int)va_arg(temp, int);
  360.                             ld = (long int)d;
  361.                         }
  362.                         break;
  363.                     }
  364.                 }
  365.  
  366.                 d_to_str(res, &spec[i], ld);
  367.             } else if (s21_strchr("feE", spec[i].specif) != s21_NULL) {
  368.                 long double d_arg;
  369.                 if (spec[i].lenght == 'L') {
  370.                     d_arg = va_arg(temp, long double);
  371.                 } else {
  372.                     d_arg = (long double)va_arg(temp, double);
  373.                 }
  374.                 float_e_to_str(&(spec[i]), d_arg, res, spec[i].specif);
  375.             } else if (spec[i].specif == 'x' || spec[i].specif == 'X') {
  376.                 int_to_oct_hex_str(&(spec[i]), va_arg(temp, long long int), res, 16);
  377.             } else if (spec[i].specif == 'o') {
  378.                 int_to_oct_hex_str(&(spec[i]), va_arg(temp, long long int), res, 8);
  379.             } else if (spec[i].specif == 'g' || spec[i].specif == 'G') {
  380.                 g_to_str(&(spec[i]), res, temp);
  381.             } else if (spec[i].specif == 'p') {
  382.                 pnt_to_str(&(spec[i]), va_arg(temp, long long int), res);
  383.             } else if (spec[i].specif == '%') {
  384.                 s21_strcat(res, "%");
  385.             } else if (spec[i].specif == 'n') {
  386.                 int *d = va_arg(temp, int *);
  387.                 *d = (int)s21_strlen(res);
  388.             } else if (spec[i].specif == 's') {
  389.                 str_to_res_str(&(spec[i]), va_arg(temp, char *), res);
  390.             }
  391.             j += spec[i].size_format - 1;
  392.             i++;
  393.         } else {
  394.             *(res + s21_strlen(res)) = *(format + j);
  395.         }
  396.     }
  397.     va_end(temp);
  398.     s21_size_t res_len = s21_strlen(res);
  399.     s21_strcpy(str, res);
  400.     free(res);
  401.     *(str + res_len) = '\0';
  402.     return (int)res_len;
  403. }
  404.  
  405. void check_ch(parcer_t *spec, char *str, int ch) {
  406.     char *temp_str = (char *)calloc(50, sizeof(char));
  407.     char c = ch;
  408.     if (spec->width != 0) {
  409.         char empty = (s21_strchr(spec->flag, '0') == s21_NULL) ? ' ' : '0';
  410.         if (s21_strchr(spec->flag, '-') != s21_NULL) {
  411.             temp_str[0] = c;
  412.             for (int i = 1; i < spec->width; i++)
  413.                 *(temp_str + i) = empty;
  414.         } else {
  415.             for (int i = 0; i < spec->width - 1; i++)
  416.                 *(temp_str + i) = empty;
  417.             temp_str[spec->width - 1] = c;
  418.         }
  419.     } else {
  420.         temp_str[0] = c;
  421.     }
  422.     s21_strcat(str, temp_str);
  423.     free(temp_str);
  424. }
  425.  
  426. int int_to_str(char *str, long int d) {
  427.     long temp = d;
  428.     int i = 0;
  429.     do {
  430.         temp /= 10;
  431.         i++;
  432.     } while (temp != 0);
  433.     int size = i;
  434.     i--;
  435.     do {
  436.         *(str + i) = d % 10 + '0';
  437.         d /= 10;
  438.         i--;
  439.     } while (d != 0);
  440.     return size;
  441. }
  442.  
  443. int str_to_int(char *str, int size) {
  444.     int sign = check_sign(&str, &size);
  445.     int d = 0;
  446.     for (int i = 0; i < size; i++) {
  447.         if (*(str + i) >= '0' && *(str + i) <= '9') {
  448.             d *= 10;
  449.             d += (*(str + i) - '0');
  450.         }
  451.     }
  452.     d *= sign;
  453.     return d;
  454. }
  455.  
  456. void pnt_to_str(parcer_t *spec, long long int int_p, char *str) {
  457.     int_to_oct_hex_str(spec, int_p, str, 16);
  458. }
  459.  
  460. void str_to_res_str(parcer_t *spec, char *arg_str, char *str) {
  461.     int size = spec->accur < (int) s21_strlen(arg_str) &&
  462.     spec->accur != -1 ? spec->accur : (int) s21_strlen(arg_str);
  463.     int dif_size = spec->width - size;
  464.     if (dif_size > 0 && s21_strchr(spec->flag, '-') == s21_NULL) {
  465.         for (int i = 0; i < dif_size; i++) {
  466.             *(str + s21_strlen(str)) = ' ';
  467.         }
  468.     }
  469.     s21_strncat(str, arg_str, size);
  470.     if (dif_size > 0 && s21_strchr(spec->flag, '-') != s21_NULL) {
  471.         for (int i = 0; i < dif_size; i++) {
  472.             *(str + s21_strlen(str)) = ' ';
  473.         }
  474.     }
  475. }
  476.  
  477. int parcer(const char *format, parcer_t *spec) {
  478.     char flag[] = "-+ 0#";
  479.     char width[] = "1234567890*";
  480.     char accur[] = ".1234567890*";
  481.     char lenght[] = "hlL";
  482.     char specif[] = "cdieEfgGosuxXpn%";
  483.     char *refer_pointer[5] = {flag, width, accur, lenght, specif};
  484.     int counter = 0;
  485.     int counter_buff;
  486.     int ref_point_p = 0;
  487.     int i = 0;
  488.     while (*(format + counter) != 0) {
  489.         if (*(format + counter) == '%' && ref_point_p == 0) {
  490.             spec[i].spec_pos = counter;
  491.             ++counter;
  492.             for (ref_point_p = 0; ref_point_p < 5; ref_point_p++) {
  493.                 char *str = (char *)calloc(20, sizeof(char));
  494.                 search_spec(&counter_buff, &counter, format, refer_pointer[ref_point_p], str, ref_point_p);
  495.                 switch (ref_point_p) {
  496.                     case 0: {
  497.                         s21_strcpy(spec[i].flag, str);
  498.                         break;
  499.                     }
  500.                     case 1: {
  501.                         if (s21_strchr(str, '*') != s21_NULL) {
  502.                             spec[i].width_arg_flag = 1;
  503.                         } else {
  504.                             spec[i].width_arg_flag = 0;
  505.                             int size = s21_strlen(str);
  506.                             spec[i].width = str_to_int(str, size);
  507.                         }
  508.                         break;
  509.                     }
  510.                     case 2: {
  511.                         if (s21_strchr(str, '*') != s21_NULL) {
  512.                             spec[i].accur_arg_flag = 1;
  513.                         } else {
  514.                             spec[i].accur = 0;
  515.                             spec[i].accur_arg_flag = 0;
  516.                             int size = s21_strlen(str);
  517.                             if (size == 0) {
  518.                                 spec[i].accur = -1;
  519.                             } else {
  520.                                 spec[i].accur = str_to_int(str, size);
  521.                             }
  522.                         }
  523.                         break;
  524.                     }
  525.                     case 3: {
  526.                         spec[i].lenght = str[0];
  527.                         break;
  528.                     }
  529.                     case 4: {
  530.                         spec[i].specif = str[0];
  531.                         break;
  532.                     }
  533.                     default:
  534.                         break;
  535.                 }
  536.                 free(str);
  537.             }
  538.             ref_point_p = 0;
  539.             if (s21_strchr(specif, spec[i].specif) == s21_NULL) {
  540.                 spec[i].specif = '%';
  541.             }
  542.             spec[i].size_format = counter - spec[i].spec_pos;
  543.             i++;
  544.         } else {
  545.             ++counter;
  546.         }
  547.     }
  548.     return i;
  549. }
  550.  
  551. void search_spec(int *counter_buff,
  552.                  int *counter,
  553.                  const char *format,
  554.                  char *refer,
  555.                  char *str,
  556.                  int ref_point_p) {
  557.     *counter_buff = *counter;
  558.     *counter = check(*counter, format, refer, ref_point_p);
  559.     test_output(*counter, *counter_buff, format, str);
  560. }
  561.  
  562. int check(int counter, const char *str, const char *refer, int ref_point_p) {
  563.     int i = 0;
  564.     while (s21_strchr(refer, (int)*(str + counter)) != s21_NULL) {
  565.         ++counter;
  566.         i++;
  567.         if (ref_point_p == 4 && i == 1) {
  568.             break;
  569.         }
  570.     }
  571.     return counter;
  572. }
  573.  
  574. void test_output(int counter, int counter_buff, const char *format, char *str) {
  575.     int i = 0;
  576.     while (counter_buff < counter) {
  577.         *(str + i) = *(format + counter_buff);
  578.         ++counter_buff;
  579.         i++;
  580.     }
  581. }
  582.  
  583. void int_to_oct_hex_str(parcer_t *spec, long long int d, char *str, int n) {
  584.     char lenght = spec->lenght;
  585.     switch (lenght) {
  586.         case 'h':
  587.             if (spec->specif == 'u') {
  588.                 d = (unsigned short int)d;
  589.             } else {
  590.                 d = (short int)d;
  591.             }
  592.             break;
  593.         case 'l':
  594.             if (spec->specif == 'u') {
  595.                 d = (unsigned long int)d;
  596.             } else {
  597.                 d = (long int)d;
  598.             }
  599.             break;
  600.  
  601.         default:
  602.             break;
  603.     }
  604.     char *buff = (char *)calloc(40, sizeof(char));
  605.     char *temp_str = buff;
  606.     do {
  607.         if (n == 16) {
  608.             switch (d % n) {
  609.                 case 10: {
  610.                     *temp_str = spec->specif == 'x' || spec->specif == 'p' ? 'a' : 'A';
  611.                     break;
  612.                 }
  613.                 case 11: {
  614.                     *temp_str = spec->specif == 'x' || spec->specif == 'p' ? 'b' : 'B';
  615.                     break;
  616.                 }
  617.                 case 12: {
  618.                     *temp_str = spec->specif == 'x' || spec->specif == 'p' ? 'c' : 'C';
  619.                     break;
  620.                 }
  621.                 case 13: {
  622.                     *temp_str = spec->specif == 'x' || spec->specif == 'p' ? 'd' : 'D';
  623.                     break;
  624.                 }
  625.                 case 14: {
  626.                     *temp_str = spec->specif == 'x' || spec->specif == 'p' ? 'e' : 'E';
  627.                     break;
  628.                 }
  629.                 case 15: {
  630.                     *temp_str = spec->specif == 'x' || spec->specif == 'p' ? 'f' : 'F';
  631.                     break;
  632.                 }
  633.                 default: {
  634.                     *temp_str = (d % n) + '0';
  635.                     break;
  636.                 }
  637.             }
  638.         } else {
  639.             *temp_str = (d % n) + '0';
  640.         }
  641.         temp_str++;
  642.         d /= n;
  643.     } while (d != 0);
  644.     char empty = ' ';
  645.     s21_size_t size = s21_strlen(buff) > (s21_size_t)spec->accur ? s21_strlen(buff) : (s21_size_t)spec->accur;
  646.     if (s21_strchr(spec->flag, '#') != s21_NULL) {
  647.         switch (spec->specif) {
  648.             case 'o': {
  649.                 s21_strcat(str, "0");
  650.                 break;
  651.             }
  652.             case 'x': {
  653.                 s21_strcat(str, "0x");
  654.                 break;
  655.             }
  656.             case 'X': {
  657.                 s21_strcat(str, "0X");
  658.                 break;
  659.             }
  660.             default:
  661.                 break;
  662.         }
  663.     }
  664.     if (spec->specif == 'p') {
  665.         s21_strcat(str, "0x");
  666.     }
  667.     if ((s21_size_t)spec->width > size && s21_strchr(spec->flag, '-') == s21_NULL) {
  668.         for (s21_size_t i = 0; i < spec->width - size; i++) {
  669.             *(str + s21_strlen(str)) = empty;
  670.         }
  671.     }
  672.     if (temp_str - buff < spec->accur) {
  673.         int accur_dif = spec->accur - (temp_str - buff);
  674.         for (int i = 0; i < accur_dif; i++) {
  675.             *(str + s21_strlen(str)) = '0';
  676.         }
  677.     }
  678.     while (temp_str != buff) {
  679.         *(str + s21_strlen(str)) = *(--temp_str);
  680.     }
  681.     if ((s21_size_t)spec->width > size && s21_strchr(spec->flag, '-') != s21_NULL) {
  682.         for (s21_size_t i = 0; i < spec->width - size; i++) {
  683.             *(str + s21_strlen(str)) = empty;
  684.         }
  685.     }
  686.     free(buff);
  687. }
  688.  
  689. void g_to_str(parcer_t *spec, char *str, va_list temp) {
  690.     char specif;
  691.     long double arg_lf;
  692.     if (spec->lenght == 'L') {
  693.         arg_lf = va_arg(temp, long double);
  694.     } else {
  695.         arg_lf = (long double)va_arg(temp, double);
  696.     }
  697.     char buff1[200] = "";
  698.     int st = float_e_to_str(spec, arg_lf, buff1, spec->specif == 'g' ? 'e' : 'E');
  699.     if (spec->accur == -1) {
  700.         spec->accur = 6;
  701.     } else if (spec->accur == 0) {
  702.         spec->accur = 1;
  703.     }
  704.     if (spec->accur > st && st >= -4) {
  705.         spec->accur -= (st + 1);
  706.         specif = 'f';
  707.     } else {
  708.         spec->accur -= 1;
  709.         specif = spec->specif == 'g' ? 'e' : 'E';
  710.     }
  711.     char buff2[200] = "";
  712.     float_e_to_str(spec, arg_lf, buff2, specif);
  713.     s21_strcat(str, buff2);
  714. }
  715.  
  716. int float_e_to_str(parcer_t *spec, long double e, char *str, char specif) {
  717.     char *buff = (char *)calloc(100, sizeof(char));
  718.     char *temp_str = buff;
  719.     int count_l_d = 0;
  720.     if (s21_strchr(spec->flag, '+') != s21_NULL && e >= 0) {
  721.         *temp_str = '+';
  722.         temp_str++;
  723.     }
  724.     if (e < -DBL_EPSILON) {
  725.         *temp_str = '-';
  726.         temp_str++;
  727.         e = -e;
  728.     }
  729.     if (s21_strchr(spec->flag, ' ') != s21_NULL &&
  730.         s21_strchr(buff, '+') == s21_NULL &&
  731.         s21_strchr(buff, '-') == s21_NULL) {
  732.         *temp_str = ' ';
  733.         temp_str++;
  734.     }
  735.     int size;
  736.     int accur;
  737.     if (spec->specif != 'g' && spec->specif != 'G') {
  738.         accur = (spec->accur == -1) ? 6 : spec->accur;
  739.     } else {
  740.         accur = spec->accur;
  741.     }
  742.     if (specif == 'e' || specif == 'E') {
  743.         while (fabsl(e) >= 10 || fabsl(e) < 1) {
  744.             if (fabsl(e) > 0 && fabsl(e) < 1) {
  745.                 e *= 10;
  746.                 count_l_d--;
  747.             } else if (fabsl(e) >= 10) {
  748.                 e /= 10;
  749.                 count_l_d++;
  750.             } else {
  751.                 break;
  752.             }
  753.         }
  754.         *temp_str = ((char)e) + '0';
  755.     } else if (specif == 'f') {
  756.         size = int_to_str(temp_str, (long int)e);
  757.         temp_str += size - 1;
  758.     }
  759.     if (accur != 0 || s21_strchr(spec->flag, '#') != s21_NULL) {
  760.         *(++temp_str) = '.';
  761.     }
  762.     e -= (int)e;
  763.     e += FLT_EPSILON;
  764.     for (int i = 0; i < accur; i++) {
  765.         e *= 10;
  766.         long double temp;
  767.         e = modfl(e, &temp);
  768.         *(++temp_str) = ((int)temp) + '0';
  769.     }
  770.     if (spec->specif == 'g' || spec->specif == 'G') {
  771.         while (*temp_str == '0') {
  772.             *temp_str = 0;
  773.             temp_str--;
  774.         }
  775.     }
  776.     int temp_count = count_l_d;
  777.     if (s21_strchr("eE", specif) != s21_NULL) {
  778.         *(++temp_str) = (specif == 'e') ? 'e' : 'E';
  779.         *(++temp_str) = temp_count < 0 ? '-' : '+';
  780.         if (abs(temp_count) < 10) {
  781.             *(++temp_str) = '0';
  782.             *(++temp_str) = abs(temp_count) + '0';
  783.         } else {
  784.             *(++temp_str) = abs(temp_count) / 10 + '0';
  785.             temp_count %= 10;
  786.             *(++temp_str) = abs(temp_count) + '0';
  787.         }
  788.     }
  789.     char empty = ' ';
  790.     if (s21_strchr(spec->flag, '0') != s21_NULL) {
  791.         empty = '0';
  792.     }
  793.     if ((s21_size_t)spec->width > s21_strlen(buff) && s21_strchr(spec->flag, '-') == s21_NULL) {
  794.         s21_size_t size = s21_strlen(buff);
  795.         for (s21_size_t i = 0; i < spec->width - size; i++) {
  796.             *(str + s21_strlen(str)) = empty;
  797.         }
  798.     }
  799.     s21_strcat(str, buff);
  800.     if ((s21_size_t)spec->width > s21_strlen(buff) && s21_strchr(spec->flag, '-') != s21_NULL) {
  801.         s21_size_t size = s21_strlen(buff);
  802.         for (s21_size_t i = 0; i < spec->width - size; i++) {
  803.             *(str + s21_strlen(str)) = empty;
  804.         }
  805.     }
  806.     int size_res;
  807.  
  808.     if (specif == 'e' || specif == 'E') {
  809.         size_res = count_l_d;
  810.     } else {
  811.         size_res = -1;
  812.     }
  813.     free(buff);
  814.     return size_res;
  815. }
  816.  
  817. void d_to_str(char *out1, parcer_t *spec, long int d) {
  818.     char *flags = spec->flag;
  819.     char out[201];
  820.     out[200] = '\0';
  821.     for (int i_tmp = 0; i_tmp < 200; i_tmp++) {
  822.         out[i_tmp] = ' ';
  823.     }
  824.     int w = spec->width;
  825.     int accur = spec->accur;
  826.     accur = accur == -1 ? 0 : accur;
  827.     int accurf = accur;
  828.     if (s21_strchr(flags, '0') != s21_NULL && (spec->accur == -1)) {
  829.         accur = w - 1;
  830.     }
  831.     int ii = 0;
  832.     char sym = (s21_strchr(flags, '+') != s21_NULL && spec->specif != 'u') ? '+' : 0;
  833.     accurf = accur + ((s21_strchr(flags, '+') != NULL) || (d < 0));
  834.     int dig_count = dig_counter(d);
  835.     w = (w < accur) ? accur : w;
  836. int i_tmp;
  837.     if (s21_strchr(flags, '0') != s21_NULL) {
  838.         if (spec->accur == -1) {
  839.             i_tmp = 0;} else {
  840.             i_tmp = (w - accur);
  841.         }
  842.  
  843.         for (; i_tmp < w; i_tmp++) {
  844.             out[i_tmp] = '0';
  845.         }
  846.     }
  847.     if (d < (long int)0) {
  848.         sym = '-';
  849.         d = d * -1;
  850.     } else {
  851.         if ((s21_strchr(flags, '+') != NULL) || (s21_strchr(flags, ' ') != NULL)) {
  852.             dig_count++;
  853.         }
  854.     }
  855.     w = (w < dig_count) ? dig_count : w;
  856.     if (w > dig_count || accur > dig_count) {
  857.         ii = w - ((accur < dig_count) ? dig_count : accurf);
  858.     }
  859.     if (s21_strchr(flags, '-')) {
  860.         ii = 0;
  861.     }
  862.     if (s21_strchr(flags, ' ') != 0 && sym == '\0') {
  863.         out[ii] = ' ';
  864.         ii++;
  865.     } else {
  866.         if (sym != '\0') {
  867.             out[ii] = sym;
  868.             ii++;
  869.         }
  870.     }
  871.     dig_count = dig_counter(d);
  872.     long int del = stepen(dig_counter(d));
  873.     long int d_tmp = d;
  874.     get_zero(out, &ii, ii + accur - dig_count);
  875.     for (int i = 0; i < dig_count; i++, ii++) {
  876.         out[ii] = ((long int)d_tmp / del) + 48;
  877.         d_tmp = d_tmp - del * ((long int)d_tmp / del);
  878.         del = del / 10;
  879.     }
  880.     out[ii] = '\0';
  881.     s21_strcat(out1, out);
  882. }
  883.  
  884. long int stepen(long int b) {
  885.     long int result = 1;
  886.     for (long int i = 1; i < b; i++) {
  887.         result = result * 10;
  888.     }
  889.     return result;
  890. }
  891.  
  892. int dig_counter(long int d) {
  893.     int i = 1;
  894.     long int temp = 10;
  895.     if (d < 0) {
  896.         (d = d * -1);
  897.         i++;
  898.     }
  899.     while (1) {
  900.         if (d >= temp) {
  901.             temp = temp * 10;
  902.             i++;
  903.         } else {
  904.             break;
  905.         }
  906.     }
  907.     return (i);
  908. }
  909.  
  910. void get_zero(char *out, int *ii, int stop) {
  911.     for (; *ii < stop; *ii = *ii + 1) {
  912.         out[*ii] = '0';
  913.     }
  914. }
  915.  
  916. int s21_sscanf(const char *str, const char *format, ...) {
  917.     int used_args = 0;
  918.     parcer_t spec[20];
  919.     int num_exp_args = parcer(format, spec);
  920.     int size_src = s21_strlen(str);
  921.     int j = 0;
  922.     va_list list_args;
  923.     va_start(list_args, format);
  924.     for (int i = 0; i < num_exp_args && j < size_src; i++) {
  925.         if (spec[i].specif == 'c') {
  926.             spec[i].width = 1;
  927.         }
  928.         char *buff = (char *)calloc(size_src, sizeof(char));
  929.         int k = 0;
  930.         while (*(str + j) != ' ' && *(str + j) != '\n' && *(str + j) != '\t' && j < size_src) {
  931.             *(buff + k) = *(str + j);
  932.             k++;
  933.             if (spec[i].width != 0 && spec[i].width == k) {
  934.                 break;
  935.             }
  936.             j++;
  937.         }
  938.         j++;
  939.         while (*(str + j) == ' ' || *(str + j) == '\n' || *(str + j) == '\t') {
  940.             j++;
  941.         }
  942.         if (spec[i].width_arg_flag == 0) {
  943.             if (spec[i].width == 0) {
  944.                 spec[i].width = s21_strlen(buff);
  945.             }
  946.             s21_size_t size = (s21_size_t)spec[i].width < s21_strlen(buff) ?
  947.             (s21_size_t)spec[i].width : s21_strlen(buff);
  948.             if (spec[i].specif == 'c') {
  949.                 str_to_ch(buff, &(spec[i]), list_args);
  950.                 used_args++;
  951.             } else if (spec[i].specif == 's') {
  952.                 sscanf_str_to_res(&(spec[i]), buff, list_args);
  953.                 used_args++;
  954.             } else if (s21_strchr("duxXo", spec[i].specif) != s21_NULL) {
  955.                 int d;
  956.                 if (s21_strchr("xX", spec[i].specif) != s21_NULL) {
  957.                     d = 16;
  958.                 } else if (spec[i].specif == 'o') {
  959.                     d = 8;
  960.                 } else {
  961.                     d = 10;
  962.                 }
  963.                 hex_oct_dec_convert(buff, size, &(spec[i]), list_args, d);
  964.                 used_args++;
  965.             } else if (spec[i].specif == 'i') {
  966.                 hex_oct_str_to_int(&(spec[i]), buff, list_args);
  967.                 used_args++;
  968.             } else if (spec[i].specif == 'n') {
  969.                 int *n_arg = va_arg(list_args, int *);
  970.                 *n_arg = j - k - 2;
  971.                 if (*n_arg < 0)
  972.                     *n_arg = 0;
  973.                 used_args++;
  974.             } else if (s21_strchr("eEfgG", spec[i].specif) != s21_NULL) {
  975.                 double_arg_to_str(buff, size, &(spec[i]), list_args);
  976.                 used_args++;
  977.             } else if (spec[i].specif == 'p') {
  978.                 hex_oct_dec_convert(buff, size, &(spec[i]), list_args, 16);
  979.                 used_args++;
  980.             }
  981.         }
  982.         free(buff);
  983.     }
  984.     va_end(list_args);
  985.     return used_args;
  986. }
  987.  
  988. void sscanf_str_to_res(parcer_t *spec, char *src, va_list list_args) {
  989.     if (spec->lenght == 'l') {
  990.         wchar_t *warg = va_arg(list_args, wchar_t *);
  991.         for (s21_size_t i = 0; i < s21_strlen(src); i++) {
  992.             warg[i] = (wchar_t)(*(src + i));
  993.         }
  994.     } else {
  995.         char *s_arg = va_arg(list_args, char *);
  996.         clean_str(s_arg, s21_strlen(s_arg));
  997.         s21_strncat(s_arg, src, (spec->width < (int)s21_strlen(src) ? spec->width : (int)s21_strlen(src)));
  998.     }
  999. }
  1000.  
  1001. void hex_oct_str_to_int(parcer_t *spec, char *buff, va_list list_args) {
  1002.     int size = spec->width < (int)s21_strlen(buff) ? spec->width : (int)s21_strlen(buff);
  1003.     if (*buff == '0') {
  1004.         if (*(buff + 1) == 'x' || *(buff + 1) == 'X') {
  1005.             hex_oct_dec_convert(buff + 2, size - 2, spec, list_args, 16);
  1006.         } else {
  1007.             hex_oct_dec_convert(buff + 1, size - 1, spec, list_args, 8);
  1008.         }
  1009.     } else {
  1010.         hex_oct_dec_convert(buff, size, spec, list_args, 10);
  1011.     }
  1012. }
  1013.  
  1014. void hex_oct_dec_convert(char *buff, int size, parcer_t *spec, va_list list_args, int s_s) {
  1015.     int_type int_val;
  1016.     unsigned long arg = 0;
  1017.     int sign = check_sign(&buff, &size);
  1018.     for (int i = 0; i < size; i++) {
  1019.         arg *= s_s;
  1020.         if (*(buff + i) >= '0' && *(buff + i) <= '9') {
  1021.             arg += (*(buff + i) - '0');
  1022.         } else if (*(buff + i) >= 'a' && *(buff + i) <= 'f') {
  1023.             arg += (*(buff + i) - 'W');
  1024.         } else if (*(buff + i) >= 'A' && *(buff + i) <= 'F') {
  1025.             arg += (*(buff + i) - '7');
  1026.         }
  1027.     }
  1028.     arg *= sign;
  1029.     if (s21_strchr("uxXo", spec->specif) != s21_NULL) {
  1030.         if (spec->lenght == 'l') {
  1031.             int_val.lu = va_arg(list_args, unsigned long *);
  1032.             *(int_val.lu) = (unsigned long)arg;
  1033.         } else if (spec->lenght == 'h') {
  1034.             int_val.hu = va_arg(list_args, unsigned short *);
  1035.             *(int_val.hu) = (unsigned short)arg;
  1036.         } else {
  1037.             int_val.u = va_arg(list_args, unsigned *);
  1038.             *(int_val.u) = (unsigned)arg;
  1039.         }
  1040.     } else if (s21_strchr("di", spec->specif) != s21_NULL) {
  1041.         if (spec->lenght == 'l') {
  1042.             int_val.ld = va_arg(list_args, long *);
  1043.             *(int_val.ld) = (long)arg;
  1044.         } else if (spec->lenght == 'h') {
  1045.             int_val.h = va_arg(list_args, short *);
  1046.             *(int_val.h) = (short)arg;
  1047.         } else {
  1048.             int_val.d = va_arg(list_args, int *);
  1049.             *(int_val.d) = (int)arg;
  1050.         }
  1051.     } else if (spec->specif == 'p') {
  1052.         void *p_arg = va_arg(list_args, void **);
  1053.         int_val.ld = p_arg;
  1054.         *(int_val.ld) = (long)arg;
  1055.     }
  1056. }
  1057.  
  1058. void str_to_ch(char *buff, parcer_t *spec, va_list list_arg) {
  1059.     char *ch;
  1060.     wchar_t *wch;
  1061.     if (spec->lenght == 'l') {
  1062.         wch = va_arg(list_arg, wchar_t *);
  1063.         *wch = (wchar_t)*buff;
  1064.     } else {
  1065.         ch = va_arg(list_arg, char *);
  1066.         *ch = *buff;
  1067.     }
  1068. }
  1069.  
  1070. int check_sign(char **str, int *size) {
  1071.     int sign = 1;
  1072.     if (**str == '-') {
  1073.         *str += 1;
  1074.         *size -= 1;
  1075.         sign = -1;
  1076.     }
  1077.     return sign;
  1078. }
  1079.  
  1080. void double_arg_to_str(char *buff, int size, parcer_t *spec, va_list list_args) {
  1081.     double_type doub_val;
  1082.     long double f_arg = 0;
  1083.     int left = 0;
  1084.     int sign = *buff == '-' ? -1 : 1;
  1085.     int i = 0;
  1086.     if (*buff == '-' || *buff == '+') {
  1087.         i++;
  1088.     }
  1089.     for (; i < size && *(buff + i) != '.'; i++) {
  1090.         left *= 10;
  1091.         left += (*(buff + i) - '0');
  1092.     }
  1093.     f_arg = left;
  1094.     int count_num = 0;
  1095.     int right = 0;
  1096.     if (i < size && *(buff + i) == '.') {
  1097.         for (++i; i < size && *(buff + i) != 'e' && *(buff + i) != 'E'; i++) {
  1098.             right *= 10;
  1099.             right += (*(buff + i) - '0');
  1100.             count_num++;
  1101.         }
  1102.     }
  1103.     f_arg += right / pow(10, count_num);
  1104.     if (i < size && (*(buff + i) == 'e' || *(buff + i) == 'E')) {
  1105.         i++;
  1106.         int st_sign = *(buff + i) == '-' ? -1 : 1;
  1107.         int st = 0;
  1108.         count_num = 0;
  1109.         for (++i; i < size && count_num < 2; i++) {
  1110.             st *= 10;
  1111.             st += (*(buff + i) - '0');
  1112.             count_num++;
  1113.         }
  1114.         f_arg *= pow(10, st * st_sign);
  1115.     }
  1116.     f_arg *= sign;
  1117.     if (spec->lenght == 'l') {
  1118.         doub_val.doub = va_arg(list_args, double *);
  1119.         *(doub_val.doub) = (double)f_arg;
  1120.     } else if (spec->lenght == 'L') {
  1121.         doub_val.l_doub = va_arg(list_args, long double *);
  1122.         *(doub_val.l_doub) = (long double)f_arg;
  1123.     } else {
  1124.         doub_val.f = va_arg(list_args, float *);
  1125.         *(doub_val.f) = (float)f_arg;
  1126.     }
  1127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement