|
|
@@ -50,7 +50,7 @@ void echo (char * string) { |
|
|
|
} |
|
|
|
|
|
|
|
void fatal_failure (int condition, char * message) { // We use this function to abort the program if condition is met and to print the message. |
|
|
|
if (condition == FALSE) { // If the variable 'condition' is not equal to 0, we execute the code in curly braces. |
|
|
|
if (condition == TRUE) { // If the variable 'condition' is not equal to 0, we execute the code in curly braces. |
|
|
|
echo ("[\033[1;31mExiting\033[0m] "); // Simply printing the message using our 'echo' function, but we also use some colours, more on that later. |
|
|
|
echo (message); // Also, notice how "this or that" is implicity 'char *' type... Maybe it's too early to explain it at this point. |
|
|
|
echo ("\n"); // This will only print a new line, we'll see how to use it later. |
|
|
@@ -167,57 +167,64 @@ int string_compare (char * string_0, char * string_1) { |
|
|
|
} |
|
|
|
@ |
|
|
|
|
|
|
|
And I used this approach below to show that you can solve the problem using different solutions... |
|
|
|
And I used this approach below to show that you can solve the problem using different solutions... You'll notice that "limited" versions have variable 'offset' of type integer. We |
|
|
|
use it to interate the strings, while in "unlimited" versions, we iterate on pointers to those strings, which are pushed to the stack. Both versions work, both versions give the |
|
|
|
same results, you can use any of them. |
|
|
|
*/ |
|
|
|
|
|
|
|
int string_compare (char * string_0, char * string_1) { |
|
|
|
fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer."); |
|
|
|
fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer."); // This will be seen in next 5 functions too, we don't want NULL here. |
|
|
|
fatal_failure (string_1 == NULL, "string_compare: Source string is null pointer."); |
|
|
|
|
|
|
|
for (; (* string_0 != CHARACTER_NULL) && (* string_1 != CHARACTER_NULL); ++string_0, ++string_1) { |
|
|
|
if (* string_0 != * string_1) { |
|
|
|
return (FALSE); |
|
|
|
for (; (* string_0 != CHARACTER_NULL) && (* string_1 != CHARACTER_NULL); ++string_0, ++string_1) { // We iterate until either string reaches the null character. |
|
|
|
if (* string_0 != * string_1) { // In case that characters at the same offset are different: |
|
|
|
return (FALSE); // > We return FALSE, 0, since strings aren't the same... |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return (TRUE); |
|
|
|
return (TRUE); // Otherwise, strings are same, we return TRUE, 1. |
|
|
|
} |
|
|
|
|
|
|
|
char * string_copy (char * string_0, char * string_1) { |
|
|
|
fatal_failure (string_0 == NULL, "string_copy: Destination string is null pointer."); |
|
|
|
fatal_failure (string_1 == NULL, "string_copy: Source string is null pointer."); |
|
|
|
|
|
|
|
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) { |
|
|
|
* string_0 = * string_1; |
|
|
|
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) { // This time and in next function, we iterate only source string. |
|
|
|
* string_0 = * string_1; // And we assign character at the same offset to destination string (aka copy it). |
|
|
|
} |
|
|
|
|
|
|
|
* string_0 = * string_1; // Copying null termination, since the loop stopped on that condition. |
|
|
|
* string_0 = * string_1; // Copying null termination, since the loop stopped on that condition. |
|
|
|
|
|
|
|
return (string_0); |
|
|
|
return (string_0); // Lastly, we return the destination string, in order to be able to bind functions. |
|
|
|
} |
|
|
|
|
|
|
|
char * string_concatenate (char * string_0, char * string_1) { |
|
|
|
fatal_failure (string_0 == NULL, "string_concatenate: Destination string is null pointer."); |
|
|
|
fatal_failure (string_1 == NULL, "string_concatenate: Source string is null pointer."); |
|
|
|
|
|
|
|
string_0 += string_length (string_0); |
|
|
|
|
|
|
|
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) { |
|
|
|
* string_0 = * string_1; |
|
|
|
string_0 += string_length (string_0); // We'll first offset destination string to the end of it. |
|
|
|
// Because we want to start copying from the end, aka concatenate it. |
|
|
|
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) { // The rest of the function is same as string_copy, so: |
|
|
|
* string_0 = * string_1; // We could even use it here, but that defies the purpose of learning now. |
|
|
|
} |
|
|
|
|
|
|
|
* string_0 = CHARACTER_NULL; |
|
|
|
* string_0 = CHARACTER_NULL; // Again, assign null termination. |
|
|
|
|
|
|
|
return (string_0); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
As for "limited" versions of previous 3 functions, they do the same thing, but are capped to some variable 'limit'. These functions have their own use-case, for example, if |
|
|
|
strings aren't null terminated, if you're not sure that they are null terminated, if we're dealing with binary (not textual) data (casted to char *), and many more cases. |
|
|
|
*/ |
|
|
|
|
|
|
|
int string_compare_limit (char * string_0, char * string_1, int limit) { |
|
|
|
int offset; |
|
|
|
|
|
|
|
fatal_failure (string_0 == NULL, "string_compare_limit: Destination string is null pointer."); |
|
|
|
fatal_failure (string_1 == NULL, "string_compare_limit: Source string is null pointer."); |
|
|
|
|
|
|
|
for (offset = 0; offset != limit; ++offset) { |
|
|
|
for (offset = 0; offset < limit; ++offset) { |
|
|
|
if (string_0 [offset] != string_1 [offset]) { |
|
|
|
return (FALSE); |
|
|
|
} |
|
|
@@ -230,12 +237,13 @@ char * string_copy_limit (char * string_0, char * string_1, int limit) { |
|
|
|
int offset; |
|
|
|
|
|
|
|
fatal_failure (string_0 == NULL, "string_copy_limit: Destination string is null pointer."); |
|
|
|
fatal_failure (string_1 == NULL, "string_copy_limit: Source string is null pointer."); |
|
|
|
|
|
|
|
if ((limit <= 0) || (string_1 == NULL)) { |
|
|
|
return (string_0); |
|
|
|
} |
|
|
|
|
|
|
|
for (offset = 0; offset != limit; ++offset) { |
|
|
|
for (offset = 0; offset < limit; ++offset) { |
|
|
|
string_0 [offset] = string_1 [offset]; |
|
|
|
} |
|
|
|
|
|
|
@@ -246,6 +254,7 @@ char * string_concatenate_limit (char * string_0, char * string_1, int limit) { |
|
|
|
int offset, length_0, length_1; |
|
|
|
|
|
|
|
fatal_failure (string_0 == NULL, "string_concatenate_limit: Destination string is null pointer."); |
|
|
|
fatal_failure (string_1 == NULL, "string_concatenate_limit: Source string is null pointer."); |
|
|
|
|
|
|
|
if ((limit <= 0) || (string_1 == NULL)) { |
|
|
|
return (string_0); |
|
|
@@ -254,7 +263,7 @@ char * string_concatenate_limit (char * string_0, char * string_1, int limit) { |
|
|
|
length_0 = string_length (string_0); |
|
|
|
length_1 = string_length (string_1); |
|
|
|
|
|
|
|
for (offset = 0; (offset != length_1) && (offset != limit); ++offset) { |
|
|
|
for (offset = 0; (offset < length_1) && (offset < limit); ++offset) { |
|
|
|
string_0 [length_0 + offset] = string_1 [offset]; |
|
|
|
} |
|
|
|
|
|
|
|