Replace char in C (including empty char)

Experts,

I'm trying to write a replace function in C and it works fine except when I want to replace a character with an empty character (not blank but nothing). So in that case, the string should become shorter and I have to change the index I in the loop. Can you help me on how to do this right?

Thanks!
char * replace_string(char *org_str, char *replace_str, char *in_string) 
{
    char * out_str = NULL;
    int str_size = strlen(in_string) + 1 * sizeof(char);
    int i = 0;

    // Allocate some space for the output string
    out_str = (char *) malloc(str_size);
    if (out_str == NULL) {
        fprintf(stderr, "ERROR: replace_string, unable to allocate space for out_str\n");
        return out_str;
    }

    strncpy(out_str, in_string, str_size); 
    out_str[str_size - 1] = '\0'; 

    // Replace the chars
    for(i = 0; i < str_size; ++i){
     if (out_str[i] == *org_str){
        if (replace_str == NULL) {
            //what to do now?
        }
        out_str[i] = *replace_str;
     }
    }

    return out_str;
}

Open in new window

php-newbieAsked:
Who is Participating?
 
Todd GerbertIT ConsultantCommented:
Sorry, I did catch that it's supposed to be C - I just wasn't paying close enough attention to what I was doing.

Of course, this still is useful only if you're looking for char-by-char and not string-by-string replacement.
char* replace_chars(char char_to_replace, char replacement_char, char* original_string)
{
	int cbNewString = (strlen(original_string) + 1) * sizeof(char);
	char* new_string = NULL;
	char* new_string_temp = NULL;

	// If the replacement_char is null the new string will
	// be n chars smaller than the original, where n is
	// the number of occurences of char_to_replace in original_string
	if(replacement_char == NULL)
		cbNewString -= count_char_occurences(original_string, char_to_replace);

	new_string = (char*)malloc(cbNewString);
	if(new_string == NULL)
	{
		fprintf(stderr, "Could not allocate memory.");
		return NULL;
	}
	memset(new_string, 0, cbNewString);

	// make copy of the pointer so we can modify it
	// without affecting the original pointer
	new_string_temp = new_string;

	// Continue until the char pointed to by
	// original_string is NULL
	while(*original_string != NULL)
	{
		// If this is char to replace then...
		if(*original_string == char_to_replace)
		{
			// if replacement char is non-null put
			// the replacement char where new_string_temp
			// points
			if(replacement_char != NULL)
				*new_string_temp = replacement_char;
			else
			{
				// Otherwise, if this is the char we want
				// to replace but the replacement is NULL
				// then don't do anything, just advance
				// original_string to the next char and
				// continue immediately with next iteration of loop
				original_string++;
				continue;
			}
		}
		else
		{
			// Otherwise if this is not the char we
			// want to replace, just copy the char from
			// the original string to the new string
			*new_string_temp = *original_string;
		}
		
		// Advance each string to the next char
		original_string++;
		new_string_temp++;
	}

	return new_string;
}

Open in new window



>> i would suggest you to post your code in a separate question
Honestly, I'm not particularly interested in the answers to the questions I asked - really I just wanted you guys to point out what was wrong with the code so php-newbie doesn't get bad advice.
0
 
Infinity08Commented:
So, in the case where it fails, is replace_str NULL, or does it point to a '\0' character ? Or something else ?

In other words, how do you call this function when it fails ?
0
 
sarabandeCommented:
a few things that are wrong:

1. the sizeof(char) should be multiplied with (strlen(in_string) + 1)  and not only with 1. like in math the multiplication was done before addition if not forced otherwise by setting parantheses. the statement works nevertheless but only cause sizeof(char) == 1 by definition.

2. if you want replace a sequence of chars with another sequence, you should not try to replace single characters as you do in the second loop. instead you should do a strncmp on the in_string + i with org_str and if that matches you replace the full substring with the replace_str for example by doing strcat on an sufficient large new buffer.

Sara
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
trinitrotolueneDirector - Software EngineeringCommented:
As far as I can see replace_str should be a string and not a single character. So there's a problem in your logic

You are always only writing only the 1st character to the new string
out_str[j] = *replace_str  

Is this what you want??

If you want to parse thru' all your replace_str characters then you should have something like


 
if (replace_str[i] == '') 
{
   continue;
}
   
and corresponding logic to change the index into the out_str array. You can use a different variable for this instead of i

Open in new window

0
 
sarabandeCommented:
do you want to replace only the first match or all matches?

the second is more difficult cause you wouldn't be able to calculate the size of output string in advance. so in case the replace_str is larger than the org_str you would need to realloc the out_str and grow it by the difference in length.

Sara
0
 
ltgbauCommented:
So do you need a function that replace char by char or string by string?
0
 
Todd GerbertIT ConsultantCommented:
Your code kinda-sorta looks like you're replacing char-by-char, not string-by-string, but that's a bit of a guess on my part, plus I just learned C/C++ yesterday so I may be way off base, so I will leave it to others here to make corrections. ;)

Specifically I'm not sure what should or should not be a const char* vs. a char*, if it's safe to increment the pointers in this fashion, and if malloc()'ed memory needs to be explicitly free()'ed prior to the end of main() or is it implicitly released on program termination?

int count_char_occurences(char* string_to_search, char char_to_count)
{
	int char_count = 0;

	while(*string_to_search != '\0')
	{
		if(*string_to_search == char_to_count)
			char_count++;
		string_to_search++;
	}

	return char_count;
}

char* replace_chars(char char_to_replace, char replacement_char, char* original_string)
{
	int cbNewString = (strlen(original_string) + 1) * sizeof(char);

	// If the replacement_char is null the new string will
	// be n chars smaller than the original, where n is
	// the number of occurences of char_to_replace in original_string
	if(replacement_char == NULL)
		cbNewString -= count_char_occurences(original_string, char_to_replace);

	char* new_string = (char*)malloc(cbNewString);
	if(new_string == NULL)
	{
		fprintf(stderr, "Could not allocate memory.");
		return NULL;
	}
	memset(new_string, 0, cbNewString);

	// make copy of the pointer so we can modify it
	// without affecting the original pointer
	char* new_string_temp = new_string;

	// Continue until the char pointed to by
	// original_string is NULL
	while(*original_string != NULL)
	{
		// If this is char to replace then...
		if(*original_string == char_to_replace)
		{
			// if replacement char is non-null put
			// the replacement char where new_string_temp
			// points
			if(replacement_char != NULL)
				*new_string_temp = replacement_char;
			else
			{
				// Otherwise, if this is the char we want
				// to replace but the replacement is NULL
				// then don't do anything, just advance
				// original_string to the next char and
				// continue immediately with next iteration of loop
				original_string++;
				continue;
			}
		}
		else
		{
			// Otherwise if this is not the char we
			// want to replace, just copy the char from
			// the original string to the new string
			*new_string_temp = *original_string;
		}
		
		// Advance each string to the next char
		original_string++;
		new_string_temp++;
	}

	return new_string;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char test[] = "Hello World!";
	
	char* newString = replace_chars('l', NULL, test);

	printf("%s\r\nPress any key to continue...", newString);
	getch();
	
	free(newString);

	return 0;
}

Open in new window

0
 
sarabandeCommented:
tgerbert, the q. is probably for C programming only as you could see in the title.

also it is not usual in C/C++ TA to post full code samples (even if they come from a newbee). also the code you posted is visual c++ 'flavored' code which is ok when the author does but not when the original poster has posted pure c code.

i would suggest you to post your code in a separate question. then we could answer your special q. on your code without going off-topic here.

Sara
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.