Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include "s21_string.h"
- #include <stdarg.h>
- #include <stdlib.h>
- void input(char *a);
- void output(char *a);
- /*
- int main() {
- char str1[] = "123456";
- char str2[] = "123rgt45";
- printf("Длина\n");
- s21_size_t l1 = s21_strlen(str1);
- printf("len = %d\n\n", l1);
- //input(str1);
- //input(str2);
- printf("сравнение\n");
- int f = s21_strcmp(str1, str2);
- printf("flag = %d\n", f);
- printf("original flag = %d\n\n", strcmp(str1, str2));
- printf("сравнение n\n");
- int g = s21_strncmp(str1, str2, 15);
- printf("flag = %d\n", g);
- printf("original flag = %d\n\n", strncmp(str1, str2, 15));
- printf("копия\n");
- char buf[60]="";
- s21_strcpy(buf, str1);
- printf("flag = %s\n", buf);
- char buf3[60] = "";
- strcpy(buf3, str1);
- printf("original flag = %s\n\n", buf3);
- printf("копия n\n");
- char buf1[30]="";
- s21_strncpy(buf1, str1, 3);
- printf("flag = %s\n", buf1);
- char buf2[30] = "";
- printf("qqqq%s",strncpy(buf2, str1, 3));
- printf("original flag = %s\n\n", buf2);
- output(str1);
- output(str2);
- return 0;
- }
- */
- void input(char *a) {
- for (int i = 0; i < 10; i++) {
- scanf("%c ", a+i);
- }
- }
- void output(char *a) {
- int len = s21_strlen(a);
- for (int p = 0; p < len; p++) {
- printf("%c", *(a+p));
- }
- printf("\n");
- }
- int s21_strcmp(const char *str1, const char *str2) {
- int f = 0;
- int len = s21_strlen(str1);
- int len2 = s21_strlen(str2);
- if(len2 > len)
- len = len2;
- for (int i = 0; i < len; ++i) {
- if (*(str1+i) > *(str2+i)) {
- f = *(str1+i) - *(str2+i);
- break;
- } else if (*(str1+i) < *(str2+i)){
- // f = -1;
- f = *(str1+i) - *(str2+i);
- break;
- }
- }
- return f;
- }
- /*
- int s21_strcmp(const char *str1, const char *str2) {
- int returnable = 0;
- if (str1 != NULL && str2 != NULL) {
- s21_size_t len = s21_strlen(str1);
- s21_size_t len2 = s21_strlen(str2);
- if(len2 > len) {
- returnable = -str2[len];
- } else if (len2 < len) {
- len = len2;
- returnable = str1[len2];
- }
- s21_size_t i = 0;
- while (i < len && str1[i] == str2[i]) {
- i++;
- }
- if (i < len && str1[i] > str2[i]) {
- returnable = 1;
- } else if (i < len && str1[i] < str2[i]){
- returnable = -1;
- }
- }
- return returnable;
- }
- */
- s21_size_t s21_strlen(const char *str)
- {
- s21_size_t len = 0;
- while (1) {
- if (*(str+len) == '\0')
- break;
- len++;
- }
- return len;
- }
- int s21_strncmp(const char *str1, const char *str2, s21_size_t n) {
- int f = 0;
- for (int i = 0; i < n; ++i) {
- if (*(str1+i) > *(str2+i)) {
- f = *(str1+i) - *(str2+i);
- break;
- } else if (*(str1+i) < *(str2+i)){
- f = *(str1+i) - *(str2+i);
- break;
- }
- }
- return f;
- }
- char *s21_strcpy(char *dest, const char *src) {
- int i = 0;
- while (*(src+i) != '\0') {
- *(dest+i) = *(src+i);
- i++;
- }
- return dest;
- }
- char *s21_strncpy(char *dest, const char *src, int n) {
- for (int i = 0; i < n; i++) {
- *(dest+i) = *(src+i);
- }
- return dest;
- }
- /*
- int s21_memcmp(const void *str1, const void *str2, s21_size_t n) {
- int returnable = 0;
- char *str1_temp = (char *)str1;
- char *str2_temp = (char *)str2;
- if (str1_temp == NULL && str2_temp == NULL) {
- returnable = 0;
- } else if (str1_temp == NULL && str2_temp != NULL) {
- returnable = 1;
- } else if (str1_temp != NULL && str2_temp == NULL) {
- returnable = -1;
- } else {
- s21_size_t i = 0;
- while (i < n && str1_temp[i] == str2_temp[i]) {
- i++;
- }
- if (i != n && str1_temp[i] > str2_temp[i]) {
- returnable = 1;
- } else if (i != n && str1_temp[i] < str2_temp[i]) {
- returnable = -1;
- } else {
- returnable = 0;
- }
- }
- return returnable;
- }
- */
- int s21_sprintf(char *output, char *str, ...)
- {
- va_list ap; /* point on next unnamed argument */
- va_start(ap, str); /* set 'ap' on 1-st unnamed argument */
- int out_len = 0; // массив, куда осуществляется вывод, он должен задаваться как аргумент s21_sprintf, но пока так
- for (char *p = str; *p; p++) //циклом пробегаем каждый символ строки (например "%*.*d %d % f %+-*d %% %n %*.*s %-#*.*o %.*i %*c %*x %#X\n")
- {
- if (*p !='%') // если символ не процент, то просто печатаем его
- {
- out_len ++;
- output[strlen(output)] = *p;
- continue;
- }
- char flag1 = -1; //задаём значения подспецификаторов по умолчанию
- char flag3 = -1;
- int width = -1;
- int prec = -1;
- char lenght = -1;
- ++p; //переключаемся на следующий символ и если он один из флагов, то считываем его
- while(1) { //цикл бесконечный, так как флагов можно ставить хоть сколько
- if (*p == '-' || *p == '+' || *p == ' ') {
- if (*p == '+' || *p == ' ') {
- if (flag1 == '+')
- flag1 = '+';
- else
- flag1 = *p;
- }
- if (*p == '-'){
- flag3 = *p;
- }
- ++p;
- } else {
- break;
- }
- }
- if (*p == '*') { //следующий символ, и если он ширина, то считываем её. Один раз проверяем наличие шиирны, так как ширину можно указывать только один раз, в отличии от флагов
- width = va_arg(ap, int);
- ++p;
- }
- if(*p == '.' && *(p+1) == '*') { //следующий символ, и если он точность, то считываем его.
- prec = va_arg(ap, int);
- p+=2;
- }
- if (*p == 'h' || *p == 'l') {
- lenght = *p;
- ++p;
- }
- switch(*p) // теперь смотрим спецификаторы.
- {
- case 'c':
- {
- char ival;
- ival = (char) va_arg(ap, int);
- if (flag3 != '-' && width != -1){
- for (int i = 0; i < width - 1; ++i) {
- output[strlen(output)] = ' ';
- out_len++;
- }
- }
- output[strlen(output)] = ival;
- out_len++;
- if (flag3 == '-' && width != -1){
- for (int i = 0; i < width - 1; ++i) {
- output[strlen(output)] = ' ';
- out_len++;
- }
- }
- break;
- }
- case 'u':
- {
- unsigned long int ival = 0;
- if (lenght == 'l')
- ival = (unsigned long int)va_arg(ap, unsigned long int);
- else
- ival = (unsigned long int)va_arg(ap, unsigned int);
- char buf[21]="";
- IntStr(buf,1, ival, -1, flag3, width, prec);
- out_len+=strlen(buf);
- strcat(output, buf);
- break;
- }
- case 'd':
- {
- long int ival = 0;
- if (lenght == 'l')
- ival = (long int)va_arg(ap, long int);
- else
- ival = (long int)va_arg(ap, int);
- char buf[50]="";
- IntStr(buf,1, ival, flag1, flag3, width, prec);
- out_len+=strlen(buf);
- strcat(output, buf);
- break;
- }
- case 'i':
- {
- long int ival = 0;
- if (lenght == 'l')
- ival = (long int)va_arg(ap, long int);
- else
- ival = (long int)va_arg(ap, int);
- char buf[50]="";
- IntStr(buf,1, ival, flag1, flag3, width, prec);
- out_len+=strlen(buf);
- strcat(output, buf);
- break;
- break;
- }
- case 'f':
- {
- double dval = 0.;
- dval = va_arg(ap, double);
- char buf[50]="";
- DoubleStr(buf, dval, flag1, flag3, width, prec);
- out_len+=strlen(buf);
- strcat(output, buf);
- break;
- }
- case 's':
- {
- char *buf = malloc(sizeof(char));
- int k = 0;
- for(char *sval = va_arg(ap, char *); *sval; sval++) {
- k++;
- if (prec < k && prec > 0)
- continue;
- buf = realloc(buf, k*sizeof(char));
- *(buf+k-1)=*sval;
- out_len++;
- }
- int l = strlen(buf);
- if (flag3 != '-') {
- for (int i = 0; i < width - l; ++i) {
- strcat(output, " ");
- out_len++;
- }
- }
- strcat(output, buf);
- free(buf);
- if (flag3 == '-') {
- for (int i = 0; i < width - l; ++i) {
- strcat(output, " ");
- out_len++;
- }
- }
- break;
- }
- case '%':
- {
- strcat(output, "%");
- out_len++;
- break;
- }
- default:
- {
- output[strlen(output)] = *p;
- break;
- }
- }
- }
- va_end(ap); /* clean all */
- printf("\n");
- return out_len;
- }
- char* IntStr(char *buf,int is_int, long int n, char flag, char flag3, int width, int prec) {
- //char *index = buf;
- int len = LenInt(n);
- int fprec = 0; //длина числа
- if (prec != -1 && is_int == 0) {
- fprec = prec+1;
- }
- int tr_len = len;
- if (prec != -1 && prec > len && is_int == 1) //если задана точность, то длина числа будет равна точности
- len = prec;
- int full_len = len;
- int i = 0;
- int j = 0;
- if (flag == ' ' && n >= 0 || flag == '+' && n > 0 || n < 0) //если заданы флаги пробел и + или число отрицательное, то фактическая длина больше на единицу, так как нужно печатать плюс, минус или пробел
- full_len++;
- if (flag3 == -1 && width != -1){ //если задана ширина и нет флага 0 или -, то печатаем сначала пробелы, затем число
- for (j; j < width - full_len - fprec; ++j) {
- *(buf+j) = ' ';
- }
- }
- if (flag == ' ' && n >= 0) { //если если флаг пробел, то перед числом ставим пробел
- buf+=j;
- *(buf++) = ' ';
- buf-=j;
- }
- if (flag == '+' && n > 0) { //если если флаг +, то перед положительным числом ставим плюс
- buf+=j;
- *(buf++) = '+';
- buf-=j;
- }
- if (n < 0) { //если число отрицательно, то перед ним печатаем минус
- buf+=j;
- *(buf++) = '-';
- buf-=j;
- n = -n;
- }
- if (n == 0) { //если число ноль, то печатаем ноль (ноль приходится отдельно обрабатывать, иначе не работает)
- buf+=j;
- *(buf++) ='0';
- buf-=j;
- }
- while (n > 0) { //непосредственно вывод самого числа
- *(buf+j+len-i-1) = (n % 10) | '0';
- n /= 10;
- i++;
- }
- if (is_int == 1)
- for (int h=0; h < prec - tr_len; h++){ //а это, если задана точность, вывод дополнительных нулей
- *(buf+j+len-i-1) = '0';
- i++;
- }
- if (flag3 == '-' && width != -1 && is_int == 1) { //если флаг - и задана ширина, то после числа пробелы печатаем
- for (j; j < width - full_len - fprec; ++j)
- *(buf+len-1+j+1) = ' ';
- }
- return(buf);
- }
- int LenInt(int n) {
- int len = 0;
- if (n < 0)
- n = n * (-1);
- while(n > 0) {
- len++;
- n /= 10;
- }
- return len;
- }
- char* DoubleStr(char *buf, long double n, char flag, char flag3, int width, int prec) {
- int len = LenInt((int)n);
- if (flag == ' ' && n >= 0 || flag == '+' && n > 0 || n < 0) //если заданы флаги пробел и + или число отрицательное, то фактическая длина больше на единицу, так как нужно печатать плюс, минус или пробел
- len++;
- if (prec == -1)
- prec = 6;
- IntStr(buf,0, (int)n, flag, flag3, width, prec);
- if (prec != 0)
- strcat(buf, ".");
- else
- strcat(buf, " ");
- if (n < 0) {
- n = n * (-1);
- }
- n = n - (long int)n;
- for (int i = 0; i < prec; i++) {
- n *= 10;
- buf[strlen(buf)] = n + '0';
- n = n - (int)n;
- }
- if (flag3 == '-') {
- for (int i = 0; i < width - (len + prec + 1); i ++)
- buf[strlen(buf)] = ' ';
- }
- return buf;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement