For an assignment, I am building a replaceString
function with using the 3 functions I already built (findString
, removeString
, insertString
) that replaces the first occurrence of s1
string inside the source
string with s2
string. It came out fine, except when s1
is a single character (ex. "a"
) or a null string ""
, an error "stack smashing detected" will show below it:
hello, world
*** stack smashing detected ***: /home/noob/ex1008 terminated
======= Backtrace: =========
...
======= Memory map: ========
...
And this happens when I call the function like this:
char text[] = "a world";
replaceString ( text, "a", "hello," );
or
char text[] = " world";
replaceString ( text, "", "hello," );
However, this error can be eliminated when I declare array length like this:
char text[10] = "a world";
replaceString ( text, "a", "hello," )
Or if the length of s1 is more than 1:
char text[] = "the world";
replaceString ( text, "the", "hello," )
I don't understand why it acts like this. Is there a way that I don't need to declare array length when I input single character string or null string? See my whole code below:
#include <stdlib.h>
#include <stdio.h>
int main ( int argc, char *argv[] )
{
char text[] = "a world";
void replaceString ( char source[], const char s1[], const char s2[] );
replaceString ( text, "a", "hello," );
printf ( "%s\n", text );
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
/*
* === FUNCTION =========================================================
* Name: replaceString
* Description: Replaces first occurrence of s1 in source with s2.
* ========================================================================
*/
void replaceString ( char source[], const char s1[], const char s2[] )
{
int start, removeLength;
int findString ( const char source[], const char search[] );
void removeString ( char source[], const int start, const int remove );
void insertString ( char source[], const char insert[],
const int start );
start = findString ( source, s1 );
if ( start == -1 )
return;
for ( removeLength = 0; s1[removeLength]; removeLength++ );
removeString ( source, start, removeLength );
insertString ( source, s2, start );
} /* ----- end of function replaceString ----- */
/*
* === FUNCTION =========================================================
* Name: findString
* Description: Determines if one character string exists inside other
* string. If found, returns location in source string. If
* not, returns -1.
* ========================================================================
*/
int findString ( const char source[], const char search[] )
{
int i, j;
for ( i = 0; source[i]; i++ )
for ( j = 0; source[i + j] == search[j] || ! search [j]; j++ )
if ( ! search[j] )
return i;
return -1;
} /* ----- end of function findString ----- */
/*
* === FUNCTION =========================================================
* Name: removeString
* Description: Removes a specified number of characters from a character
* string.
* ========================================================================
*/
void removeString ( char source[], const int start,
const int remove )
{
char output[80];
int i, j = 0;
for ( i = 0; source[i]; i++ )
if ( i < start || i >= start + remove )
output[j++] = source[i];
output[j] = '\0';
for ( i = 0; output[i]; i++)
source[i] = output[i];
source[i] = '\0';
} /* ----- end of function removeString ----- */
/*
* === FUNCTION =========================================================
* Name: insertString
* Description: Inserts a string into another string.
* ========================================================================
*/
void insertString ( char source[], const char insert[],
const int start )
{
char output[80];
int i = 0, j = 0, k = 0;
while ( source[i] ) {
if ( i < start || ! insert[k] )
output[j++] = source[i++];
else
output[j++] = insert[k++];
}
output[j] = '\0';
for ( i = 0; output[i]; i++ )
source[i] = output[i];
source[i] = '\0';
} /* ----- end of function insertString ----- */