/
solidbase
/
C3_s21_stringplus
Обзор
Документация
Войти
/
solidbase
/
C3_s21_stringplus
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
src/s21_string.c
435 строк
11 KB
Raccoon Stefani
Change pointer aligment to right based on Google style
01 фев 2026, 11:13
01 фев 2026, 11:13
4b9ec1b
Код
Авторство
О чём код?
#include "s21_string.h" #include "s21_errno.h" //--------------- string.h Functions ------------------------------------------ // 1. Searches for the first occurrence of the character c (an unsigned char) in // the first n bytes of the string pointed to, by the argument str. // void *s21_memchr(const void *str, int c, s21_size n) { ; } // 2. Compares the first n bytes of str1 and str2. // int s21_memcmp(const void *str1, const void *str2, s21_size n) { ; } // 3. Copies n characters from src to dest. // void *s21_memcpy(void *dest, const void *src, s21_size n) { ; } // 4. Copies the character c (an unsigned char) to the first n characters of the // string pointed to, by the argument str. // void *s21_memset(void *str, int c, s21_size n) { ; } // 5. Appends the string pointed to, by src to the end of the string pointed to, // by dest up to n characters long. char* s21_strncat(char* dest, const char* src, s21_size n) { char* dest_end = dest; while (*dest_end != '\0') { dest_end++; } s21_size i = 0; while (i < n && src[i] != '\0') { dest_end[i] = src[i]; i++; } dest_end[i] = '\0'; return dest; } // 6. Searches for the first occurrence of the character c (an unsigned char) in // the string pointed to, by the argument str. char* s21_strchr(const char* str, int c) { char* result = S21_NULL; char target = (char)c; for (s21_size i = 0; str[i] != '\0' && result == S21_NULL; i++) { if (str[i] == target) { result = (char*)(str + i); } } if (result == S21_NULL && str[s21_strlen(str)] == target) { result = (char*)(str + s21_strlen(str)); } return result; } // 7. Compares at most the first n bytes of str1 and str2. int s21_strncmp(const char* str1, const char* str2, s21_size n) { const unsigned char* ptr1 = (const unsigned char*)str1; const unsigned char* ptr2 = (const unsigned char*)str2; int result = 0; for (s21_size i = 0; i < n && result == 0; i++) { if (ptr1[i] != ptr2[i]) { result = ptr1[i] - ptr2[i]; } if (ptr1[i] == '\0' || ptr2[i] == '\0') { break; } } return result; } // 8. Copies up to n characters from the string pointed to, by src to dest. char* s21_strncpy(char* dest, const char* src, s21_size n) { s21_size i = 0; for (i = 0; i < n && src[i] != '\0'; i++) { dest[i] = src[i]; } for (; i < n; i++) { dest[i] = '\0'; } return dest; } // 9. Calculates the length of the initial segment of str1 which consists // entirely of characters not in str2. s21_size s21_strcspn(const char* str1, const char* str2) { s21_size count = 0; int found = 0; for (s21_size i = 0; str1[i] != '\0' && !found; i++) { int is_in_str2 = 0; for (s21_size j = 0; str2[j] != '\0' && !is_in_str2; j++) { if (str1[i] == str2[j]) { is_in_str2 = 1; found = 1; } } if (!found) { count++; } } return count; } // 10. Searches an internal array for the error number errnum and returns a // pointer to an error message string. You need to declare macros containing // arrays of error messages for mac and linux operating systems. Error // descriptions are available in the original library. Checking the current OS // is carried out using directives. char* s21_strerror(int errnum) { const s21_size n_errors = sizeof(s21_errors) / sizeof(s21_errors[0]); char* result = S21_NULL; if (errnum < 0 || errnum > ((int)n_errors - 1)) { // s21_unknown[15] start number static char s21_unknown[64] = "Unknown error "; int num = errnum; int neg = 0; if (num < 0) { neg = 1; num = -num; } int i = 14; while (num > 0) { s21_unknown[i++] = '0' + (num % 10); num /= 10; } if (neg) { s21_unknown[i++] = '-'; } s21_unknown[i] = '\0'; // Реверс части с цифрой int start = 14; int end = i - 1; while (start < end) { char tmp = s21_unknown[start]; s21_unknown[start] = s21_unknown[end]; s21_unknown[end] = tmp; start++; end--; } result = s21_unknown; } for (s21_size i = 0; !result && i < n_errors; i++) { if (s21_errors[i].code == errnum) { result = (char*)s21_errors[i].msg; } } return result; } // 11. Computes the length of the string str up to but not including the // terminating null character. s21_size s21_strlen(const char* str) { s21_size len = 0; for (; str[len]; len++); return len; } // 12. Finds the first character in the string str1 that matches any character // specified in str2. char* s21_strpbrk(const char* str1, const char* str2) { if (!str1 || !str2) return S21_NULL; char* result = S21_NULL; while (*str1) { for (const char* c = str2; *c; c++) { if (*str1 == *c) { result = (char*)str1; break; } } if (!result) { str1++; } else { break; } } return result; } // 13. Searches for the last occurrence of the character c (an unsigned char) in // the string pointed to by the argument str. char* s21_strrchr(const char* str, int c) { if (!str) return S21_NULL; unsigned char uc = (unsigned char)c; char* last = S21_NULL; do { if ((unsigned char)*str == uc) last = (char*)str; } while (*str++); return last; } // 14. Finds the first occurrence of the entire string needle (not including the // terminating null character) which appears in the string haystack. char* s21_strstr(const char* haystack, const char* needle) { if (!haystack || !needle) return S21_NULL; char* first = S21_NULL; s21_size l_haystack = s21_strlen(haystack); s21_size l_needle = s21_strlen(needle); if (l_needle <= l_haystack) { const char* end = haystack + (l_haystack - l_needle + 1); for (; haystack < end; haystack++) { if (!(s21_memcmp(haystack, needle, l_needle))) { first = (char*)haystack; break; } } } return first; } // 15. Breaks string str into a series of tokens separated by delim. char* s21_strtok(char* str, const char* delim) { if (!delim) return S21_NULL; static char* cur_pos = S21_NULL; static char* next_pos = S21_NULL; if (str) { cur_pos = str; } else { cur_pos = next_pos; } int first_skip = 0; while (cur_pos && *cur_pos && !first_skip) { int match = 0; for (const char* p = delim; *p && !match; p++) { if (*p == *cur_pos) match = 1; } if (match) { cur_pos++; } else { first_skip = 1; } } next_pos = s21_strpbrk(cur_pos, delim); if (next_pos) { *next_pos = '\0'; next_pos++; } else { for (next_pos = cur_pos; *next_pos; next_pos++); } return (*cur_pos) ? (cur_pos) : (S21_NULL); } //----------------------------------------------------------------------------- // Part 2. Partial implementation of the sprintf function // The next partial formatting must be supported: // Specifiers: c, d, f, s, u, % // Flags: -, +, (space) // Width description: (number) // Precision description: .(number) // Length description: h, l //----------------------------------------------------------------------------- // Part 3. Bonus. Implementation of some format modifiers of the sprintf // function The next additional format modifiers must be supported: // Specifiers: g, G, e, E, x, X, o, p // Flags: #, 0 // Width description: * // Precision description: .* // Length description: L //----------------------------------------------------------------------------- // int s21_sprintf(char *str, const char *format, ...) { ; } //----------------------------------------------------------------------------- // Part 4. Bonus. Implementation of the sscanf function // The sscanf function from the stdio.h library: //----------------------------------------------------------------------------- // int s21_sscanf(const char *str, const char *format, ...) { ; } //----------------------------------------------------------------------------- // Part 5. Bonus. Implementation of special string processing functions // Special string processing functions (from the String class in C#) //----------------------------------------------------------------------------- // Returns a copy of string (str) converted to uppercase. In case of any error, // return NULL. void* s21_to_upper(const char* str) { if (!str) return S21_NULL; s21_size str_l = s21_strlen(str); char* up_str = malloc((str_l + 1) * sizeof(char)); if (up_str) { char* p = up_str; while (*str != '\0') { if (*str >= 'a' && *str <= 'z') { *p = *str - ('a' - 'A'); } else { *p = *str; } p++; str++; } *p = '\0'; } return up_str; } // Returns a copy of string (str) converted to lowercase. In case of any error, // return NULL. void* s21_to_lower(const char* str) { if (!str) return S21_NULL; s21_size str_l = s21_strlen(str) + 1; char* lo_str = malloc(str_l * sizeof(char)); if (lo_str) { char* p = lo_str; while (*str) { if (*str >= 'A' && *str <= 'Z') { *p = *str - ('A' - 'a'); } else { *p = *str; } p++; str++; } *p = '\0'; } return lo_str; } // Returns a new string in which a specified string (str) is inserted at a // specified index position (start_index) in the given string (src). In case of // any error, return NULL. void* s21_insert(const char* src, const char* str, s21_size start_index) { if (!src || !str) return S21_NULL; char* modstr = S21_NULL; s21_size src_l = s21_strlen(src); if (start_index <= src_l) { s21_size dest_l = src_l + s21_strlen(str) + 1; char* dest = malloc(dest_l * sizeof(char)); if (dest) { char* pm = dest; const char* ps = src; while (ps < src + start_index) *pm++ = *ps++; while (*str) *pm++ = *str++; while (*ps) *pm++ = *ps++; *pm = '\0'; modstr = dest; } } return modstr; } // Returns a new string in which all leading and trailing occurrences of a set // of specified characters (trim_chars) from the given string (src) are removed. // In case of any error, return NULL. void* s21_trim(const char* src, const char* trim_chars) { if (!src) return S21_NULL; const char* trim_set; if (trim_chars == S21_NULL || *trim_chars == '\0') { trim_set = " \t\n\r\f\v"; } else { trim_set = trim_chars; } char* modstr = S21_NULL; s21_size src_l = s21_strlen(src); const char* start = src; const char* end = (*src) ? (start + src_l - 1) : start; int stop = 0; while (*start && !stop) { int match = 0; for (const char* p = trim_set; *p && !match; p++) { if (*p == *start) match = 1; } if (match) start++; else stop = 1; } stop = 0; while (end > start && !stop) { int match = 0; for (const char* p = trim_set; *p && !match; p++) { if (*p == *end) match = 1; } if (match) end--; else stop = 1; } s21_size trimstr_l = (*src && end >= start) ? (end - start + 1) : 0; char* trimstr = malloc((trimstr_l + 1) * sizeof(char)); if (trimstr) { modstr = trimstr; if (trimstr_l > 0) { while (start <= end) *trimstr++ = *start++; } *trimstr = '\0'; } return modstr; }