1
1
mirror of https://github.com/theoludwig/libcproject.git synced 2024-10-05 12:06:09 +02:00

perf: mutate strings instead of copy when possible

BREAKING CHANGE: Most of string functions mutates the string instead of copying now.
This allows better performance when copy is not needed.
It also allows more granual control.
If copy is wanted, simply use `string_copy` before calling the function.

Impacted functions are:
`string_to_uppercase`, `string_to_lowercase`, `string_replace`,
`string_trim_start`, `string_trim_end`, `string_trim`,
`string_capitalize`, `string_reverse`
This commit is contained in:
Théo LUDWIG 2023-08-06 23:17:07 +02:00
parent 01e9b71402
commit 72645da4b2
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
10 changed files with 193 additions and 222 deletions

View File

@ -92,9 +92,9 @@ touch main.c
#include "libcproject/libcproject.h" #include "libcproject/libcproject.h"
int main() { int main() {
string_t string_value = "Hello, world!"; // `string_t` is a typedef from `libcproject` string_t string = "Hello, world!"; // `string_t` is a typedef from `libcproject`
printf("%s\n", string_value); printf("%s\n", string);
printf("string_length = %ld\n", string_get_length(string_value)); // `string_get_length` is a function from `libcproject` printf("string_length = %ld\n", string_get_length(string)); // `string_get_length` is a function from `libcproject`
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
``` ```

View File

@ -1,17 +1,17 @@
#include "character.h" #include "character.h"
void character_append(string_t string_value, const char character) { void character_append(string_t string, const char character) {
size_t length = string_get_length(string_value); size_t length = string_get_length(string);
character_append_at(string_value, character, length); character_append_at(string, character, length);
} }
void character_append_at(string_t string_value, const char character, const size_t index) { void character_append_at(string_t string, const char character, const size_t index) {
size_t length = string_get_length(string_value); size_t length = string_get_length(string);
for (size_t index_string = length; index_string > index; index_string--) { for (size_t index_string = length; index_string > index; index_string--) {
string_value[index_string] = string_value[index_string - 1]; string[index_string] = string[index_string - 1];
} }
string_value[index] = character; string[index] = character;
string_value[length + 1] = '\0'; string[length + 1] = '\0';
} }
char character_to_upper(const char character) { char character_to_upper(const char character) {

View File

@ -11,21 +11,21 @@
* @brief Append a character to a string, assuming string points to an array * @brief Append a character to a string, assuming string points to an array
* with enough space. * with enough space.
* *
* @param string_value * @p
* @param character * @param character
* @since v1.0.0 * @since v1.0.0
*/ */
void character_append(string_t string_value, char character); void character_append(string_t string, char character);
/** /**
* @brief Append a character to a string at a specific index, assuming string points to an array with enough space. * @brief Append a character to a string at a specific index, assuming string points to an array with enough space.
* *
* @param string_value * @param string
* @param character * @param character
* @param index * @param index
* @since v1.0.0 * @since v1.0.0
*/ */
void character_append_at(string_t string_value, const char character, const size_t index); void character_append_at(string_t string, const char character, const size_t index);
/** /**
* @brief Converts the character to uppercase. * @brief Converts the character to uppercase.

View File

@ -18,12 +18,12 @@ char convert_digit_to_character(const char digit) {
return digit + '0'; return digit + '0';
} }
long long convert_string_to_number(const string_t string_value) { long long convert_string_to_number(const string_t string) {
bool is_negative = string_value[0] == '-'; bool is_negative = string[0] == '-';
long long integer = 0; long long integer = 0;
size_t length = string_get_length(string_value); size_t length = string_get_length(string);
for (size_t index = is_negative ? 1 : 0; index < length; index++) { for (size_t index = is_negative ? 1 : 0; index < length; index++) {
integer = integer * 10 + convert_character_to_digit(string_value[index]); integer = integer * 10 + convert_character_to_digit(string[index]);
} }
return is_negative ? integer * -1 : integer; return is_negative ? integer * -1 : integer;
} }
@ -42,23 +42,22 @@ string_t convert_number_to_string(const long long integer) {
if (is_negative) { if (is_negative) {
length++; length++;
} }
string_t string_value = malloc(sizeof(char) * length); string_t string = malloc(sizeof(char) * length);
if (string_value == NULL) { if (string == NULL) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
current = mathematics_absolute_value(integer); current = mathematics_absolute_value(integer);
size_t index = 0; size_t index = 0;
while (current != 0) { while (current != 0) {
string_value[index++] = convert_digit_to_character(current % 10); string[index++] = convert_digit_to_character(current % 10);
current = current / 10; current = current / 10;
} }
if (is_negative) { if (is_negative) {
string_value[index++] = '-'; string[index++] = '-';
} }
string_value[index] = '\0'; string[index] = '\0';
char* result = string_reverse(string_value); string_reverse(string);
free(string_value); return string;
return result;
} }
string_t convert_number_from_base_10_to_base(unsigned long long number, unsigned int base) { string_t convert_number_from_base_10_to_base(unsigned long long number, unsigned int base) {

View File

@ -37,10 +37,10 @@ char convert_digit_to_character(const char digit);
/** /**
* @brief Convert a string to a number. * @brief Convert a string to a number.
* *
* @param string_value * @param string
* @since v1.0.0 * @since v1.0.0
*/ */
long long convert_string_to_number(const string_t string_value); long long convert_string_to_number(const string_t string);
/** /**
* @brief Convert a number to a string. * @brief Convert a number to a string.

View File

@ -1,135 +1,95 @@
#include "string.h" #include "string.h"
size_t string_get_length(const string_t string_value) { size_t string_get_length(const string_t string) {
size_t length = 0; size_t length = 0;
while (string_value[length] != '\0') { while (string[length] != '\0') {
length++; length++;
} }
return length; return length;
} }
string_t string_to_uppercase(string_t string_value) { void string_to_uppercase(string_t string) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
for (size_t index = 0; index < string_length; index++) { for (size_t index = 0; index < string_length; index++) {
result[index] = character_to_upper(string_value[index]); string[index] = character_to_upper(string[index]);
} }
result[string_length] = '\0'; string[string_length] = '\0';
return result;
} }
string_t string_to_lowercase(string_t string_value) { void string_to_lowercase(string_t string) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
for (size_t index = 0; index < string_length; index++) { for (size_t index = 0; index < string_length; index++) {
result[index] = character_to_lower(string_value[index]); string[index] = character_to_lower(string[index]);
} }
result[string_length] = '\0'; string[string_length] = '\0';
return result;
} }
string_t string_replace(string_t string_value, char search, char replace) { void string_replace(string_t string, char search, char replace) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
for (size_t index = 0; index < string_length; index++) { for (size_t index = 0; index < string_length; index++) {
bool is_search_value = search == string_value[index]; bool is_search_value = search == string[index];
if (is_search_value) { if (is_search_value) {
result[index] = replace; string[index] = replace;
} else { } else {
result[index] = string_value[index]; string[index] = string[index];
} }
} }
result[string_length] = '\0'; string[string_length] = '\0';
return result;
} }
string_t string_trim_start(string_t string_value, char character) { void string_trim_start(string_t string, char character) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
size_t index_space = 0; size_t index_space = 0;
while (string_value[index_space] == character) { while (string[index_space] == character) {
index_space++; index_space++;
} }
for (size_t index = index_space; index < string_length; index++) { for (size_t index = 0; index < string_length - index_space; index++) {
result[index - index_space] = string_value[index]; string[index] = string[index + index_space];
} }
result[string_length - index_space] = '\0'; string[string_length - index_space] = '\0';
return result;
} }
string_t string_trim_end(string_t string_value, char character) { void string_trim_end(string_t string, char character) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
size_t index_space = string_length - 1; size_t index_space = string_length - 1;
while (string_value[index_space] == character) { while (string[index_space] == character) {
index_space--; index_space--;
} }
for (size_t index = 0; index < index_space + 1; index++) { string[index_space + 1] = '\0';
result[index] = string_value[index];
}
result[index_space + 1] = '\0';
return result;
} }
string_t string_trim(string_t string_value, char character) { void string_trim(string_t string, char character) {
string_t result_start = string_trim_start(string_value, character); string_trim_start(string, character);
string_t result = string_trim_end(result_start, character); string_trim_end(string, character);
free(result_start);
return result;
} }
string_t string_copy(const string_t source) { string_t string_copy(const string_t string) {
size_t source_length = string_get_length(source); size_t source_length = string_get_length(string);
string_t copy = malloc(sizeof(char) * (source_length + 1)); string_t copy = malloc(sizeof(char) * (source_length + 1));
if (copy == NULL) { if (copy == NULL) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
size_t index; size_t index;
for (index = 0; index < source_length; index++) { for (index = 0; index < source_length; index++) {
copy[index] = source[index]; copy[index] = string[index];
} }
copy[index] = '\0'; copy[index] = '\0';
return copy; return copy;
} }
string_t string_capitalize(string_t string_value) { void string_capitalize(string_t string) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
string_t result = malloc(sizeof(char) * (string_length + 1)); if (string_length == 0) {
if (result == NULL) { return;
exit(EXIT_FAILURE);
} }
for (size_t index = 0; index < string_length; index++) { string[0] = character_to_upper(string[0]);
bool is_first_character = index == 0;
if (is_first_character) {
result[index] = character_to_upper(string_value[index]);
} else {
result[index] = string_value[index];
}
}
result[string_length] = '\0';
return result;
} }
size_t string_total_occurrences_of_character(string_t string_value, char character) { size_t string_total_occurrences_of_character(string_t string, char character) {
size_t result = 0; size_t result = 0;
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
for (size_t index = 0; index < string_length; index++) { for (size_t index = 0; index < string_length; index++) {
char current_character = string_value[index]; char current_character = string[index];
if (current_character == character) { if (current_character == character) {
result += 1; result += 1;
} }
@ -137,21 +97,17 @@ size_t string_total_occurrences_of_character(string_t string_value, char charact
return result; return result;
} }
string_t string_reverse(const string_t string_value) { void string_reverse(const string_t string) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
size_t index = 0; size_t index_start = 0;
string_t result = malloc(sizeof(char) * (string_length + 1)); size_t index_end = string_length - 1;
if (result == NULL) { while (index_start < index_end) {
exit(EXIT_FAILURE); char temporary = string[index_start];
string[index_start] = string[index_end];
string[index_end] = temporary;
index_start++;
index_end--;
} }
size_t result_index = 0;
for (index = string_length - 1; index > 0; index--) {
result[result_index] = string_value[index];
result_index++;
}
result[result_index] = string_value[index];
result[string_length] = '\0';
return result;
} }
bool string_equals(const string_t string1, const string_t string2) { bool string_equals(const string_t string1, const string_t string2) {
@ -166,11 +122,11 @@ bool string_equals(const string_t string1, const string_t string2) {
return is_equal; return is_equal;
} }
bool string_get_is_integer(const string_t string_value) { bool string_get_is_integer(const string_t string) {
size_t index = 0; size_t index = 0;
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
bool is_integer = string_length >= 1; bool is_integer = string_length >= 1;
if (is_integer && string_value[0] == '-') { if (is_integer && string[0] == '-') {
if (string_length == 1) { if (string_length == 1) {
is_integer = false; is_integer = false;
} else { } else {
@ -178,7 +134,7 @@ bool string_get_is_integer(const string_t string_value) {
} }
} }
while (index < string_length && is_integer) { while (index < string_length && is_integer) {
if (!character_get_is_digit(string_value[index])) { if (!character_get_is_digit(string[index])) {
is_integer = false; is_integer = false;
} }
index++; index++;
@ -186,8 +142,8 @@ bool string_get_is_integer(const string_t string_value) {
return is_integer; return is_integer;
} }
string_t* string_split(const string_t string_value, char separator, size_t* result_size) { string_t* string_split(const string_t string, char separator, size_t* result_size) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
size_t index_string = 0; size_t index_string = 0;
size_t index_current = 0; size_t index_current = 0;
size_t index_result = 0; size_t index_result = 0;
@ -197,7 +153,7 @@ string_t* string_split(const string_t string_value, char separator, size_t* resu
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
while (index_string < string_length) { while (index_string < string_length) {
if (string_value[index_string] == separator) { if (string[index_string] == separator) {
current[index_current] = '\0'; current[index_current] = '\0';
result = realloc(result, sizeof(string_t) * (index_result + 1)); result = realloc(result, sizeof(string_t) * (index_result + 1));
if (result == NULL) { if (result == NULL) {
@ -207,7 +163,7 @@ string_t* string_split(const string_t string_value, char separator, size_t* resu
index_result++; index_result++;
index_current = 0; index_current = 0;
} else { } else {
current[index_current] = string_value[index_string]; current[index_current] = string[index_string];
index_current++; index_current++;
} }
index_string++; index_string++;
@ -230,8 +186,8 @@ string_t string_join(string_t* array, const char separator, size_t array_length)
total_length += string_get_length(array[index_array]); total_length += string_get_length(array[index_array]);
} }
size_t string_length = total_length + (array_length - 1); size_t string_length = total_length + (array_length - 1);
string_t string_value = malloc(sizeof(char) * (string_length + 1)); string_t string = malloc(sizeof(char) * (string_length + 1));
if (string_value == NULL) { if (string == NULL) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
size_t current_index = 0; size_t current_index = 0;
@ -239,17 +195,17 @@ string_t string_join(string_t* array, const char separator, size_t array_length)
string_t substring = array[index_array]; string_t substring = array[index_array];
size_t substring_length = string_get_length(substring); size_t substring_length = string_get_length(substring);
for (size_t index_substring = 0; index_substring < substring_length; index_substring++) { for (size_t index_substring = 0; index_substring < substring_length; index_substring++) {
string_value[current_index] = substring[index_substring]; string[current_index] = substring[index_substring];
current_index++; current_index++;
} }
bool is_last_character = index_array == (array_length - 1); bool is_last_character = index_array == (array_length - 1);
if (!is_last_character) { if (!is_last_character) {
string_value[current_index] = separator; string[current_index] = separator;
current_index++; current_index++;
} }
} }
string_value[string_length] = '\0'; string[string_length] = '\0';
return string_value; return string;
} }
string_t string_concatenate(string_t string1, string_t string2) { string_t string_concatenate(string_t string1, string_t string2) {
@ -271,16 +227,16 @@ string_t string_concatenate(string_t string1, string_t string2) {
return result; return result;
} }
bool string_get_has_unique_characters(const string_t string_value) { bool string_get_has_unique_characters(const string_t string) {
bool has_unique = true; bool has_unique = true;
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
struct hash_map* characters_already_seen = hash_map_initialization(); struct hash_map* characters_already_seen = hash_map_initialization();
string_t* keys = malloc(sizeof(string_t) * string_length); string_t* keys = malloc(sizeof(string_t) * string_length);
for (size_t index = 0; index < string_length; index++) { for (size_t index = 0; index < string_length; index++) {
keys[index] = NULL; keys[index] = NULL;
} }
for (size_t index = 0; index < string_length && has_unique; index++) { for (size_t index = 0; index < string_length && has_unique; index++) {
char character = string_value[index]; char character = string[index];
keys[index] = convert_character_to_string(character); keys[index] = convert_character_to_string(character);
string_t key = keys[index]; string_t key = keys[index];
if (hash_map_contains_key(characters_already_seen, key)) { if (hash_map_contains_key(characters_already_seen, key)) {
@ -299,24 +255,24 @@ bool string_get_has_unique_characters(const string_t string_value) {
return has_unique; return has_unique;
} }
string_t string_substring(const string_t string_value, size_t index_start, size_t index_end) { string_t string_substring(const string_t string, size_t index_start, size_t index_end) {
size_t substring_length = index_end - index_start + 1; size_t substring_length = index_end - index_start + 1;
string_t result = malloc(sizeof(char) * (substring_length + 1)); string_t result = malloc(sizeof(char) * (substring_length + 1));
for (size_t index = 0; index < substring_length; index++) { for (size_t index = 0; index < substring_length; index++) {
result[index] = string_value[index_start + index]; result[index] = string[index_start + index];
} }
result[substring_length] = '\0'; result[substring_length] = '\0';
return result; return result;
} }
bool string_get_is_substring(const string_t string_value, const string_t substring) { bool string_get_is_substring(const string_t string, const string_t substring) {
bool is_substring = false; bool is_substring = false;
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
size_t substring_length = string_get_length(substring); size_t substring_length = string_get_length(substring);
for (size_t index_string = 0; index_string < string_length && !is_substring; index_string++) { for (size_t index_string = 0; index_string < string_length && !is_substring; index_string++) {
size_t index_substring = 0; size_t index_substring = 0;
size_t index_considered = index_string; size_t index_considered = index_string;
while (index_substring < substring_length && string_value[index_considered] == substring[index_substring]) { while (index_substring < substring_length && string[index_considered] == substring[index_substring]) {
index_substring++; index_substring++;
index_considered++; index_considered++;
} }
@ -356,23 +312,22 @@ string_t string_get_formatted_number(const long long number, string_t separator)
} }
free(number_string); free(number_string);
result[formatted_length] = '\0'; result[formatted_length] = '\0';
string_t new_result = string_reverse(result); string_reverse(result);
free(result);
if (is_negative) { if (is_negative) {
string_t dash = convert_character_to_string('-'); string_t dash = convert_character_to_string('-');
string_t negative_result = string_concatenate(dash, new_result); string_t negative_result = string_concatenate(dash, result);
free(new_result); free(result);
free(dash); free(dash);
return negative_result; return negative_result;
} }
return new_result; return result;
} }
string_t string_get_last_occurence_of_character(const string_t string_value, char character) { string_t string_get_last_occurence_of_character(const string_t string, char character) {
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
size_t index_last_occurrence = SIZE_MAX; size_t index_last_occurrence = SIZE_MAX;
for (size_t index = 0; index < string_length; index++) { for (size_t index = 0; index < string_length; index++) {
if (string_value[index] == character) { if (string[index] == character) {
index_last_occurrence = index; index_last_occurrence = index;
} }
} }
@ -385,29 +340,29 @@ string_t string_get_last_occurence_of_character(const string_t string_value, cha
} }
size_t index_result = 0; size_t index_result = 0;
for (size_t index = index_last_occurrence; index < string_length; index++) { for (size_t index = index_last_occurrence; index < string_length; index++) {
result[index_result++] = string_value[index]; result[index_result++] = string[index];
} }
result[index_result] = '\0'; result[index_result] = '\0';
return result; return result;
} }
bool string_starts_with(const string_t string_value, const string_t prefix) { bool string_starts_with(const string_t string, const string_t prefix) {
bool starts_with = true; bool starts_with = true;
size_t prefix_length = string_get_length(prefix); size_t prefix_length = string_get_length(prefix);
for (size_t index = 0; index < prefix_length && starts_with; index++) { for (size_t index = 0; index < prefix_length && starts_with; index++) {
starts_with = string_value[index] == prefix[index]; starts_with = string[index] == prefix[index];
} }
return starts_with; return starts_with;
} }
bool string_ends_with(const string_t string_value, const string_t prefix) { bool string_ends_with(const string_t string, const string_t prefix) {
bool ends_with = true; bool ends_with = true;
size_t string_length = string_get_length(string_value); size_t string_length = string_get_length(string);
size_t prefix_length = string_get_length(prefix); size_t prefix_length = string_get_length(prefix);
size_t index_string = string_length - 1; size_t index_string = string_length - 1;
size_t index_prefix = prefix_length - 1; size_t index_prefix = prefix_length - 1;
while (index_prefix > 0 && ends_with) { while (index_prefix > 0 && ends_with) {
ends_with = string_value[index_string] == prefix[index_prefix]; ends_with = string[index_string] == prefix[index_prefix];
index_string--; index_string--;
index_prefix--; index_prefix--;
} }

View File

@ -13,93 +13,109 @@
/** /**
* @brief Return the length of a string (excluding '\0'). * @brief Return the length of a string (excluding '\0').
* *
* @param string_value * @param string
* @since v1.0.0 * @since v1.0.0
*/ */
size_t string_get_length(const string_t string_value); size_t string_get_length(const string_t string);
/** /**
* @brief Converts all the alphabetic characters in a string to uppercase. * @brief Converts all the alphabetic characters in a string to uppercase.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_to_uppercase(string_t string_value); void string_to_uppercase(string_t string);
/** /**
* @brief Converts all the alphabetic characters in a string to lowercase. * @brief Converts all the alphabetic characters in a string to lowercase.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_to_lowercase(string_t string_value); void string_to_lowercase(string_t string);
/** /**
* @brief Replace all the occurrences of search value into replace value in the string. * @brief Replace all the occurrences of search value into replace value in the string.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @param search A character search value. * @param search A character search value.
* @param replace A character containing the text to replace for match. * @param replace A character containing the text to replace for match.
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_replace(string_t string_value, char search, char replace); void string_replace(string_t string, char search, char replace);
/** /**
* @brief Removes all `character` from the start of a string. * @brief Removes all `character` from the start of a string.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_trim_start(string_t string_value, char character); void string_trim_start(string_t string, char character);
/** /**
* @brief Removes all `character` from the end of a string. * @brief Removes all `character` from the end of a string.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_trim_end(string_t string_value, char character); void string_trim_end(string_t string, char character);
/** /**
* @brief Removes all `character` from the start and end of a string. * @brief Removes all `character` from the start and end of a string.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_trim(string_t string_value, char character); void string_trim(string_t string, char character);
/** /**
* @brief Return the copy of a string. * @brief Return the copy of a string.
* *
* @param string_value * @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_copy(const string_t string_value); string_t string_copy(const string_t string);
/** /**
* @brief Capitalizes the string. * @brief Capitalizes the string.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_capitalize(string_t string_value); void string_capitalize(string_t string);
/** /**
* @brief Returns the total number of occurrences of the given character in the string. * @brief Returns the total number of occurrences of the given character in the string.
* *
* @param string_value * @param string
* @param character * @param character
* @since v1.0.0 * @since v1.0.0
*/ */
size_t string_total_occurrences_of_character(string_t string_value, char character); size_t string_total_occurrences_of_character(string_t string, char character);
/** /**
* @brief Reverse the characters in an array. * @brief Reverse the characters in a string.
* *
* @param string_value * NOTE: Mutates the string.
*
* @param string
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_reverse(const string_t string_value); void string_reverse(const string_t string);
/** /**
* @brief Check if two strings are equals. * @brief Check if two strings are equals.
@ -114,21 +130,21 @@ bool string_equals(const string_t string1, const string_t string2);
/** /**
* @brief Check if the string is a integer. * @brief Check if the string is a integer.
* *
* @param string_value * @param string
* @return true if the string is a integer, false otherwise. * @return true if the string is a integer, false otherwise.
* @since v1.0.0 * @since v1.0.0
*/ */
bool string_get_is_integer(const string_t string_value); bool string_get_is_integer(const string_t string);
/** /**
* @brief Split a string into substrings using the specified separator and return them as an array and update the pointer `result_size` to the resulting size of the created array. * @brief Split a string into substrings using the specified separator and return them as an array and update the pointer `result_size` to the resulting size of the created array.
* *
* @param string_value * @param string
* @param separator * @param separator
* @param result_size * @param result_size
* @since v1.0.0 * @since v1.0.0
*/ */
string_t* string_split(const string_t string_value, char separator, size_t* result_size); string_t* string_split(const string_t string, char separator, size_t* result_size);
/** /**
* @brief Adds all the elements of an array into a string, separated by the specified separator string. * @brief Adds all the elements of an array into a string, separated by the specified separator string.
@ -161,22 +177,22 @@ bool string_get_has_unique_characters(const string_t string);
/** /**
* @brief Returns the part of the string between the start and end indexes (both included). * @brief Returns the part of the string between the start and end indexes (both included).
* *
* @param string_value * @param string
* @param index_start * @param index_start
* @param index_end * @param index_end
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_substring(const string_t string_value, size_t index_start, size_t index_end); string_t string_substring(const string_t string, size_t index_start, size_t index_end);
/** /**
* @brief Check if a string contains a substring. * @brief Check if a string contains a substring.
* *
* @param string_value * @param string
* @param substring * @param substring
* @return true if the string contains the substring, false otherwise. * @return true if the string contains the substring, false otherwise.
* @since v1.0.0 * @since v1.0.0
*/ */
bool string_get_is_substring(const string_t string_value, const string_t substring); bool string_get_is_substring(const string_t string, const string_t substring);
/** /**
* @brief Format a number to a string with specified separator. * @brief Format a number to a string with specified separator.
@ -194,30 +210,30 @@ string_t string_get_formatted_number(const long long number, string_t separator)
/** /**
* @brief Returns a pointer to the last occurrence of character in the string. * @brief Returns a pointer to the last occurrence of character in the string.
* *
* @param string_value * @param string
* @param character * @param character
* @since v1.0.0 * @since v1.0.0
*/ */
string_t string_get_last_occurence_of_character(const string_t string_value, char character); string_t string_get_last_occurence_of_character(const string_t string, char character);
/** /**
* @brief Check if a string starts with a substring. * @brief Check if a string starts with a substring.
* *
* @param string_value * @param string
* @param prefix * @param prefix
* @return true if the string starts with the substring, false otherwise. * @return true if the string starts with the substring, false otherwise.
* @since v1.0.0 * @since v1.0.0
*/ */
bool string_starts_with(const string_t string_value, const string_t prefix); bool string_starts_with(const string_t string, const string_t prefix);
/** /**
* @brief Check if a string ends with a substring. * @brief Check if a string ends with a substring.
* *
* @param string_value * @param string
* @param prefix * @param prefix
* @return true if the string ends with the substring, false otherwise. * @return true if the string ends with the substring, false otherwise.
* @since v1.0.0 * @since v1.0.0
*/ */
bool string_ends_with(const string_t string_value, const string_t prefix); bool string_ends_with(const string_t string, const string_t prefix);
#endif #endif

View File

@ -3,20 +3,20 @@
string_t terminal_input() { string_t terminal_input() {
char character; char character;
size_t length = 1; size_t length = 1;
string_t string_value = malloc(length * sizeof(char)); string_t string = malloc(length * sizeof(char));
if (string_value == NULL) { if (string == NULL) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
*string_value = '\0'; *string = '\0';
while ((character = getchar()) != '\n' && character != EOF) { while ((character = getchar()) != '\n' && character != EOF) {
length++; length++;
string_value = realloc(string_value, length * sizeof(char)); string = realloc(string, length * sizeof(char));
if (string_value == NULL) { if (string == NULL) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
character_append(string_value, character); character_append(string, character);
} }
return string_value; return string;
} }
void terminal_print_array(void* array, size_t array_size, size_t element_size, void (*print_element)(void*)) { void terminal_print_array(void* array, size_t array_size, size_t element_size, void (*print_element)(void*)) {

6
main.c
View File

@ -4,8 +4,8 @@
#include "libcproject.h" #include "libcproject.h"
int main() { int main() {
string_t string_value = "Hello, world!"; string_t string = "Hello, world!";
printf("%s\n", string_value); printf("%s\n", string);
printf("string_length = %ld\n", string_get_length(string_value)); printf("string_length = %ld\n", string_get_length(string));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -30,46 +30,47 @@ void string_get_length_test() {
string_t string = "Hello World!"; string_t string = "Hello World!";
size_t string_length = string_get_length(string); size_t string_length = string_get_length(string);
assert(string_length == 12); assert(string_length == 12);
assert(strlen(string) == string_length);
} }
void string_to_uppercase_test() { void string_to_uppercase_test() {
string_t string = "heLlO world"; string_t string = string_copy("heLlO world");
string = string_to_uppercase(string); string_to_uppercase(string);
assert(assert_string_equal(string, "HELLO WORLD")); assert(assert_string_equal(string, "HELLO WORLD"));
free(string); free(string);
} }
void string_to_lowercase_test() { void string_to_lowercase_test() {
string_t string = "HellO WoRLd"; string_t string = string_copy("HellO WoRLd");
string = string_to_lowercase(string); string_to_lowercase(string);
assert(assert_string_equal(string, "hello world")); assert(assert_string_equal(string, "hello world"));
free(string); free(string);
} }
void string_replace_test() { void string_replace_test() {
string_t string = "hello world"; string_t string = string_copy("hello world");
string = string_replace(string, 'l', 'z'); string_replace(string, 'l', 'z');
assert(assert_string_equal(string, "hezzo worzd")); assert(assert_string_equal(string, "hezzo worzd"));
free(string); free(string);
} }
void string_trim_start_test() { void string_trim_start_test() {
string_t string = " hello world "; string_t string = string_copy(" hello world ");
string = string_trim_start(string, ' '); string_trim_start(string, ' ');
assert(assert_string_equal(string, "hello world ")); assert(assert_string_equal(string, "hello world "));
free(string); free(string);
} }
void string_trim_end_test() { void string_trim_end_test() {
string_t string = " hello world "; string_t string = string_copy(" hello world ");
string = string_trim_end(string, ' '); string_trim_end(string, ' ');
assert(assert_string_equal(string, " hello world")); assert(assert_string_equal(string, " hello world"));
free(string); free(string);
} }
void string_trim_test() { void string_trim_test() {
string_t string = " hello world "; string_t string = string_copy(" hello world ");
string = string_trim(string, ' '); string_trim(string, ' ');
assert(assert_string_equal(string, "hello world")); assert(assert_string_equal(string, "hello world"));
free(string); free(string);
} }
@ -86,8 +87,8 @@ void string_copy_test() {
} }
void string_capitalize_test() { void string_capitalize_test() {
string_t string = "hello world"; string_t string = string_copy("hello world");
string = string_capitalize(string); string_capitalize(string);
assert(assert_string_equal(string, "Hello world")); assert(assert_string_equal(string, "Hello world"));
free(string); free(string);
} }
@ -98,8 +99,8 @@ void string_total_occurrences_of_character_test() {
} }
void string_reverse_test() { void string_reverse_test() {
string_t string = "hello world"; string_t string = string_copy("hello world");
string = string_reverse(string); string_reverse(string);
assert(assert_string_equal(string, "dlrow olleh")); assert(assert_string_equal(string, "dlrow olleh"));
free(string); free(string);
} }