#include "types.h" #include #include #ifndef TEST_BUILD #define SIZE 15 int main(int argc, char *argv[]) { return 0; } #endif /** * Zjistí délku řetězce. * Všechny řetězce v C jsou ukončeny nulovým bytem. * * @param str vstupní řetězec * * @returns délku řetězce (počet znaků řetězce) */ size_t str_len(char *str) { if (str == NULL) { return 0; } int length = 0; while (true) { if (str[length] == '\0') { break; } length++; } return length; } /** * Kopíruje data po bytech v paměti o dane velikosti. * * Zdroj dat ke kopírování není změněn. * Předpokládejte, že v cíli je k dispozici dostatek volné paměti. * * hint: (char *) k pretypovani z void* * * @param dest ukazatel na paměť do které se kopíruje * @param src ukazatel na paměť ze které se kopíruje * @param n velikost kopírované paměti v bytech */ void mem_cpy(void *dest, void *src, size_t n) { if (dest == NULL || src == NULL) { return; } char *d = (char *)dest; char *s = (char *)src; // Procházíme paměť a kopírujeme byte po bytu for (size_t i = 0; i < n; i++) { d[i] = s[i]; } } /** * Najde první výskyt podřetězce v řetězci. * * Ani jeden z řetězců není změněn. * * hint: str_len * * @param str řetězec ve kterém se vyhledává * @param substr vyhledávaný podřetězec * * @returns index na kterém v řetězci začíná podřetězec, * nebo -1 pokud se podřetězec v řetězci nenachází. */ int find_substr(char *str, char *substr) { if (str == NULL || substr == NULL || str_len(substr) > str_len(str)) { return -1; } // Projdeme celý řetězec (zkrácený o délku podřetězce, protože tam už nikdy // nepůjde najít) for (size_t i = 0; i <= str_len(str) - str_len(substr); i++) { size_t j; // V druhé smyčce zkoušíme, jestli od `i` po `str_len(substr)` dojdeme bez // přerušení for (j = 0; j < str_len(substr); j++) { if (str[i + j] != substr[j]) { break; } } // Pokud jsme prošli bez přerušení, našli jsme shodu if (j == str_len(substr)) { return i; } } // Podřetězec nenalezen return -1; } /** * Nahradí podřetězec substr za nahrazující podřetězec v řetězci, * kde oba podřetězce jsou o stejné délce. * * Podřetězce nejsou změněny. * Pokud nejsou podřetězce stejně dlouhé, funkce substituci neprovede, * stejně tak pokud podřetězec není v řetězci nalezen. * * hint: mem_cpy, find_substr, str_len * * @param str řetězec ve kterém se vyhledává * @param substr vyhledávaný nahrazovaný podřetězec * @param new_substr nahrazující podřetězec */ void replace_same_length(char *str, char *substr, char *new_substr) { if (str == NULL || substr == NULL || new_substr == NULL || str_len(substr) != str_len(new_substr)) { return; } int replaceIndex = find_substr(str, substr); if (replaceIndex == -1) { return; } // Přepíšeme v paměti na nový podřetězec mem_cpy(str + replaceIndex, new_substr, str_len(new_substr)); } /** * Nahradí nahrazovaný podřetězec za nahrazující podřetězec v řetězci, * kde každý podřetězec může mít jinou velikost. * Původní řetězec je uvolněn. * * Podřetězce nejsou změněny. * V případě chyby není původní řetězec uvolněn a zůstává nezměněn. * * hint: mem_cpy, find_substr, str_len, malloc, free * * @param str dynamicky řetězec ve kterém se vyhledává * @param substr vyhledávaný nahrazovaný podřetězec * @param new_substr nahrazující podřetězec * * @returns nový řetězec vytvořený v nově alokované paměti v případě úspěchu, * pointer na původní řetězec v případě že podřetězec se v řetězci nenachází, * NULL jinak. */ char *replace(char *str, char *substr, char *new_substr) { if (str == NULL || substr == NULL || new_substr == NULL) { return NULL; } int replaceIndex = find_substr(str, substr); if (replaceIndex == -1) { return str; } size_t newSize = str_len(str) - str_len(substr) + str_len(new_substr); char *newStr = malloc(sizeof(char) * (newSize + 1)); if (newStr == NULL) { // Chyba alokace return NULL; } // Zkopírujeme část před nálezem mem_cpy(newStr, str, replaceIndex); // Zkopírujeme nový podřetězec // Musíme se posunout na místo v paměti, kde je první znak nálezu mem_cpy(newStr + replaceIndex, new_substr, str_len(new_substr)); // Zkopírujeme část za nálezem // Posuneme se na místo za první znak nálezu + délka nového podřetězce // Překopírujeme vše, co je v paměti na místě paměti původního řetězce + index // prvního nálezu + délka hledaného podřetězce mem_cpy(newStr + replaceIndex + str_len(new_substr), str + replaceIndex + str_len(substr), str_len(str) - replaceIndex - str_len(substr)); // Na konec dáme ukončovací znak newStr[newSize] = '\0'; // Uvolníme původní řetězec a vrátíme novou adresu free(str); return newStr; }