Advertisement
2607

s21_string.c

Nov 24th, 2021
2,047
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.57 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "s21_string.h"
  4. #include <stdarg.h>
  5. #include <stdlib.h>
  6.  
  7. void input(char *a);
  8. void output(char *a);
  9.  
  10. /*
  11. int main() {
  12.     char str1[] = "123456";
  13.     char str2[] = "123rgt45";
  14.     printf("Длина\n");
  15.     s21_size_t l1 = s21_strlen(str1);
  16.     printf("len = %d\n\n", l1);
  17.  
  18.     //input(str1);
  19.     //input(str2);
  20.     printf("сравнение\n");
  21.     int f = s21_strcmp(str1, str2);
  22.     printf("flag = %d\n", f);
  23.     printf("original flag = %d\n\n", strcmp(str1, str2));
  24.  
  25.     printf("сравнение n\n");
  26.     int g = s21_strncmp(str1, str2, 15);
  27.     printf("flag = %d\n", g);
  28.     printf("original flag = %d\n\n", strncmp(str1, str2, 15));
  29.  
  30.     printf("копия\n");
  31.     char buf[60]="";
  32.     s21_strcpy(buf, str1);
  33.     printf("flag = %s\n", buf);
  34.     char buf3[60] = "";
  35.     strcpy(buf3, str1);
  36.     printf("original flag = %s\n\n", buf3);
  37.  
  38.     printf("копия n\n");
  39.     char buf1[30]="";
  40.     s21_strncpy(buf1, str1, 3);
  41.     printf("flag = %s\n", buf1);
  42.     char buf2[30] = "";
  43.     printf("qqqq%s",strncpy(buf2, str1, 3));
  44.     printf("original flag = %s\n\n", buf2);
  45.  
  46.     output(str1);
  47.     output(str2);
  48.     return 0;
  49. }
  50. */
  51.  
  52. void input(char *a) {
  53.     for (int i = 0; i < 10; i++) {
  54.         scanf("%c ", a+i);
  55.     }
  56. }
  57. void output(char *a) {
  58.     int len = s21_strlen(a);
  59.     for (int p = 0; p < len; p++) {
  60.         printf("%c", *(a+p));
  61.     }
  62.     printf("\n");
  63. }
  64.  
  65. int s21_strcmp(const char *str1, const char *str2) {
  66.     int f = 0;
  67.     int len = s21_strlen(str1);
  68.     int len2 = s21_strlen(str2);
  69.     if(len2 > len)
  70.         len = len2;
  71.     for (int i = 0; i < len; ++i) {
  72.         if (*(str1+i) > *(str2+i)) {
  73.             f = *(str1+i) - *(str2+i);
  74.             break;
  75.         } else if (*(str1+i) < *(str2+i)){
  76.             // f = -1;
  77.             f = *(str1+i) - *(str2+i);
  78.             break;
  79.         }
  80.     }
  81.     return f;
  82. }
  83. /*
  84. int s21_strcmp(const char *str1, const char *str2) {
  85.     int returnable = 0;
  86.     if (str1 != NULL && str2 != NULL) {
  87.         s21_size_t len = s21_strlen(str1);
  88.         s21_size_t len2 = s21_strlen(str2);
  89.         if(len2 > len) {
  90.             returnable = -str2[len];
  91.         } else  if (len2 < len) {
  92.             len = len2;
  93.             returnable = str1[len2];
  94.         }
  95.         s21_size_t i = 0;
  96.         while (i < len && str1[i] == str2[i]) {
  97.             i++;
  98.         }
  99.         if (i < len && str1[i] > str2[i]) {
  100.             returnable = 1;
  101.         } else if (i < len && str1[i] < str2[i]){
  102.             returnable = -1;
  103.         }
  104.     }
  105.     return returnable;
  106. }
  107. */
  108. s21_size_t s21_strlen(const char *str)
  109. {
  110.     s21_size_t len = 0;
  111.     while (1) {
  112.         if (*(str+len) == '\0')
  113.             break;
  114.         len++;
  115.     }
  116.     return len;
  117. }
  118.  
  119. int s21_strncmp(const char *str1, const char *str2, s21_size_t n) {
  120.     int f = 0;
  121.     for (int i = 0; i < n; ++i) {
  122.         if (*(str1+i) > *(str2+i)) {
  123.             f = *(str1+i) - *(str2+i);
  124.             break;
  125.         } else if (*(str1+i) < *(str2+i)){
  126.             f = *(str1+i) - *(str2+i);
  127.             break;
  128.         }
  129.     }
  130.     return f;
  131. }
  132.  
  133.  
  134.  
  135. char *s21_strcpy(char *dest, const char *src) {
  136.     int i = 0;
  137.     while (*(src+i) != '\0') {
  138.         *(dest+i) = *(src+i);
  139.         i++;
  140.     }
  141.     return dest;
  142. }
  143.  
  144. char *s21_strncpy(char *dest, const char *src, int n) {
  145.     for (int i = 0; i < n; i++) {
  146.         *(dest+i) = *(src+i);
  147.     }
  148.     return dest;
  149. }
  150. /*
  151. int s21_memcmp(const void *str1, const void *str2, s21_size_t n) {
  152.     int returnable = 0;
  153.     char *str1_temp = (char *)str1;
  154.     char *str2_temp = (char *)str2;
  155.     if (str1_temp == NULL && str2_temp == NULL) {
  156.         returnable = 0;
  157.     } else if (str1_temp == NULL && str2_temp != NULL) {
  158.         returnable = 1;
  159.     } else if (str1_temp != NULL && str2_temp == NULL) {
  160.         returnable = -1;
  161.     } else {
  162.         s21_size_t i = 0;
  163.         while (i < n && str1_temp[i] == str2_temp[i]) {
  164.         i++;
  165.         }
  166.         if (i != n && str1_temp[i] > str2_temp[i]) {
  167.             returnable = 1;
  168.         } else if (i != n && str1_temp[i] < str2_temp[i]) {
  169.             returnable = -1;
  170.         } else {
  171.             returnable = 0;
  172.         }
  173.     }
  174.     return returnable;
  175. }
  176. */
  177.  
  178. int s21_sprintf(char *output, char *str, ...)
  179. {
  180.   va_list ap;             /* point on next unnamed argument */
  181.   va_start(ap, str); /* set 'ap' on 1-st unnamed argument */
  182.   int out_len = 0; // массив, куда осуществляется вывод, он должен задаваться как аргумент s21_sprintf, но пока так
  183.   for (char *p = str; *p; p++) //циклом пробегаем каждый символ строки (например "%*.*d %d % f %+-*d %% %n %*.*s %-#*.*o %.*i %*c %*x %#X\n")
  184.   {
  185.     if (*p !='%') // если символ не процент, то просто печатаем его
  186.     {
  187.       out_len ++;
  188.       output[strlen(output)] = *p;
  189.       continue;
  190.     }
  191.     char flag1 = -1; //задаём значения подспецификаторов по умолчанию
  192.     char flag3 = -1;
  193.     int width = -1;
  194.     int prec = -1;
  195.     char lenght = -1;
  196.  
  197.     ++p; //переключаемся на следующий символ и если он один из флагов, то считываем его
  198.     while(1) { //цикл бесконечный, так как флагов можно ставить хоть сколько
  199.         if (*p == '-' || *p == '+' || *p == ' ') {
  200.           if (*p == '+' || *p == ' ') {
  201.               if (flag1 == '+')
  202.                 flag1 = '+';
  203.               else
  204.                 flag1 = *p;
  205.           }
  206.           if (*p == '-'){
  207.               flag3 = *p;
  208.           }
  209.           ++p;
  210.         } else {
  211.           break;
  212.         }
  213.     }
  214.     if (*p == '*') {  //следующий символ, и если он ширина, то считываем её. Один раз проверяем наличие шиирны, так как ширину можно указывать только один раз, в отличии от флагов
  215.       width = va_arg(ap, int);
  216.       ++p;
  217.     }
  218.  
  219.     if(*p == '.' && *(p+1) == '*') { //следующий символ, и если он точность, то считываем его.
  220.       prec = va_arg(ap, int);
  221.       p+=2;
  222.     }
  223.  
  224.     if (*p == 'h' || *p == 'l') {
  225.       lenght = *p;
  226.       ++p;
  227.     }
  228.    
  229.     switch(*p)         // теперь смотрим спецификаторы.
  230.     {
  231.       case 'c':
  232.       {
  233.         char ival;
  234.         ival = (char) va_arg(ap, int);
  235.         if (flag3 != '-' && width != -1){
  236.           for (int i = 0; i < width - 1; ++i) {
  237.             output[strlen(output)] = ' ';
  238.             out_len++;
  239.           }
  240.         }
  241.         output[strlen(output)] = ival;
  242.         out_len++;
  243.         if (flag3 == '-' && width != -1){
  244.           for (int i = 0; i < width - 1; ++i) {
  245.             output[strlen(output)] = ' ';
  246.             out_len++;
  247.           }
  248.         }
  249.         break;
  250.       }
  251.       case 'u':
  252.       {
  253.         unsigned long int ival = 0;
  254.         if (lenght == 'l')
  255.             ival = (unsigned long int)va_arg(ap, unsigned long int);
  256.         else
  257.             ival = (unsigned long int)va_arg(ap, unsigned int);
  258.         char buf[21]="";
  259.         IntStr(buf,1, ival, -1, flag3, width, prec);
  260.         out_len+=strlen(buf);
  261.         strcat(output, buf);
  262.         break;
  263.       }
  264.       case 'd':
  265.       {
  266.         long int ival = 0;
  267.         if (lenght == 'l')
  268.             ival = (long int)va_arg(ap, long int);
  269.         else
  270.             ival = (long int)va_arg(ap, int);
  271.         char buf[50]="";
  272.         IntStr(buf,1, ival, flag1, flag3, width, prec);
  273.         out_len+=strlen(buf);
  274.         strcat(output, buf);
  275.         break;
  276.       }
  277.       case 'i':
  278.       {
  279.         long int ival = 0;
  280.         if (lenght == 'l')
  281.             ival = (long int)va_arg(ap, long int);
  282.         else
  283.             ival = (long int)va_arg(ap, int);
  284.         char buf[50]="";
  285.         IntStr(buf,1, ival, flag1, flag3, width, prec);
  286.         out_len+=strlen(buf);
  287.         strcat(output, buf);
  288.         break;
  289.         break;
  290.       }
  291.       case 'f':
  292.       {
  293.         double dval = 0.;
  294.         dval = va_arg(ap, double);
  295.         char buf[50]="";
  296.         DoubleStr(buf, dval, flag1, flag3, width, prec);
  297.         out_len+=strlen(buf);
  298.         strcat(output, buf);
  299.         break;
  300.       }
  301.       case 's':
  302.       {
  303.         char *buf = malloc(sizeof(char));
  304.         int k = 0;
  305.         for(char *sval = va_arg(ap, char *); *sval; sval++) {
  306.             k++;
  307.             if (prec < k && prec > 0)
  308.                 continue;
  309.             buf = realloc(buf, k*sizeof(char));
  310.             *(buf+k-1)=*sval;
  311.             out_len++;
  312.         }
  313.         int l = strlen(buf);
  314.         if (flag3 != '-') {
  315.           for (int i = 0; i < width - l; ++i) {
  316.               strcat(output, " ");
  317.               out_len++;
  318.           }
  319.         }
  320.         strcat(output, buf);
  321.         free(buf);
  322.         if (flag3 == '-') {
  323.           for (int i = 0; i < width - l; ++i) {
  324.               strcat(output, " ");
  325.               out_len++;
  326.           }
  327.         }
  328.         break;
  329.       }
  330.       case '%':
  331.       {
  332.         strcat(output, "%");
  333.         out_len++;
  334.         break;
  335.       }
  336.       default:
  337.       {
  338.         output[strlen(output)] = *p;
  339.         break;
  340.       }
  341.     }
  342.   }
  343.   va_end(ap); /* clean all */
  344.   printf("\n");
  345.   return out_len;
  346. }
  347.  
  348. char* IntStr(char *buf,int is_int, long int n, char flag, char flag3, int width, int prec) {
  349.     //char *index = buf;
  350.     int len = LenInt(n);
  351.     int fprec = 0;                                                 //длина числа
  352.     if (prec != -1 && is_int == 0) {
  353.         fprec = prec+1;
  354.     }
  355.     int tr_len = len;
  356.     if (prec != -1 && prec > len && is_int == 1)                                        //если задана точность, то длина числа будет равна точности
  357.       len = prec;
  358.     int full_len = len;
  359.     int i = 0;
  360.     int j = 0;
  361.     if (flag == ' ' && n >= 0 || flag == '+' && n > 0 || n < 0)              //если заданы флаги пробел и + или число отрицательное, то фактическая длина больше на единицу, так как нужно печатать плюс, минус или пробел
  362.         full_len++;
  363.     if (flag3 == -1 && width != -1){                                       //если задана ширина и нет флага 0 или -, то печатаем сначала пробелы, затем число
  364.         for (j; j < width - full_len - fprec; ++j) {
  365.           *(buf+j) = ' ';
  366.         }
  367.     }
  368.     if (flag == ' ' && n >= 0) {                                          //если если флаг пробел, то перед числом ставим пробел
  369.       buf+=j;
  370.       *(buf++) = ' ';
  371.       buf-=j;
  372.     }
  373.     if (flag == '+' && n > 0) {                                           //если если флаг +, то перед положительным числом ставим плюс
  374.       buf+=j;
  375.       *(buf++) = '+';
  376.       buf-=j;
  377.     }
  378.     if (n < 0) {                                                           //если число отрицательно, то перед ним печатаем минус
  379.       buf+=j;
  380.         *(buf++) = '-';
  381.         buf-=j;
  382.         n = -n;
  383.     }
  384.     if (n == 0) {                                                       //если число ноль, то печатаем ноль (ноль приходится отдельно обрабатывать, иначе не работает)
  385.       buf+=j;
  386.         *(buf++) ='0';
  387.         buf-=j;
  388.     }
  389.     while (n > 0) {                                                 //непосредственно вывод самого числа
  390.         *(buf+j+len-i-1) = (n % 10) | '0';
  391.         n /= 10;
  392.         i++;
  393.     }
  394.     if (is_int == 1)
  395.         for (int h=0; h < prec - tr_len; h++){                        //а это, если задана точность, вывод дополнительных нулей
  396.             *(buf+j+len-i-1) = '0';
  397.             i++;
  398.         }
  399.    
  400.     if (flag3 == '-' && width != -1 && is_int == 1) {                            //если флаг - и задана ширина, то после числа пробелы печатаем
  401.         for (j; j < width - full_len - fprec; ++j)
  402.           *(buf+len-1+j+1) = ' ';
  403.     }
  404.     return(buf);
  405. }
  406.  
  407. int LenInt(int n) {
  408.     int len = 0;
  409.     if (n < 0)
  410.         n = n * (-1);
  411.     while(n > 0) {
  412.       len++;
  413.       n /= 10;
  414.     }
  415.     return len;
  416. }
  417.  
  418. char* DoubleStr(char *buf, long double n, char flag, char flag3, int width, int prec) {
  419.     int len = LenInt((int)n);
  420.     if (flag == ' ' && n >= 0 || flag == '+' && n > 0 || n < 0)              //если заданы флаги пробел и + или число отрицательное, то фактическая длина больше на единицу, так как нужно печатать плюс, минус или пробел
  421.         len++;
  422.     if (prec == -1)
  423.       prec = 6;
  424.     IntStr(buf,0, (int)n, flag, flag3, width, prec);
  425.     if (prec != 0)
  426.       strcat(buf, ".");
  427.     else
  428.       strcat(buf, " ");
  429.     if (n < 0) {
  430.       n = n * (-1);
  431.     }
  432.     n = n - (long int)n;
  433.    
  434.     for (int i = 0; i < prec; i++) {
  435.         n *= 10;
  436.         buf[strlen(buf)] = n + '0';
  437.         n = n - (int)n;
  438.     }
  439.     if (flag3 == '-') {
  440.       for (int i = 0; i < width - (len + prec + 1); i ++)
  441.         buf[strlen(buf)] = ' ';
  442.     }
  443.     return buf;
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement