B Nauclér B Nauclér - 2 months ago 6
C Question

C - Replace substring in string

As a part in my process to learn C I am developing a couple of functions for string manipulations. One of these has the function of replacing substrings within a string, and is raising some questions. I am working in C99; compiling on Mac OS Sierra and FreeBSD.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *repstr(char input[], char rep[], char new[]) {

char *output = malloc(strlen(input)*5); // <- Question 2
int replen = strlen(rep);
int newlen = strlen(new);
int a, b, c = 0;

// printf("input: %ld\t%s\n", strlen(input), input); // <- Question 1

while(input[a]) {
if(input[(a+b)] == rep[b]) {
if(b == replen - 1) {
strcat(output, new);
a += replen;
c += newlen;
b=0;
}
else b++;
} else {
output[c] = input[a];
a++;
c++;
}
}

return output;
}


int main() {

char buffer[] = "This is the test string test string test test string!";
char rep[] = "test";
char new[] = "tested";

int len = strlen(buffer);

char output[len+5];

printf("input: %d\t%s\n", len, buffer); // <- Question 1
strcpy(output, repstr(buffer, rep, new));
printf("output: %ld\t%s\n", strlen(output), output);

return 0;
}


Question 1: When this line is executed in main() it causes a segfault. However, when executed within the function everything seems to work fine. Why?

Question 2: I have realized that I need a pretty large piece of memory allocated for the output to look as expected. strlen(input)*5 is an arbitrary number which seems to work, but why do I get seemingly 'random' errors when lowering the number?

NB! As this is a part of my process to learn coding in C I am not primarily interested in (more efficient) pre-fab solutions for solving the problem (already have them), but to explain the two questions listed - so that I can solve the problem myself.

Also; this is my first post in the SO forums. Hello.

Answer

Question 1: When this line is executed in main() it causes a segfault. However, when executed within the function everything seems to work fine. Why?

No, printf("input: %d\t%s\n", len, buffer); // <- Question 1 is not the cause of your segfault.

printf("output: %ld\t%s\n", strlen(output), output);

This part is, strlen doesn't return int but it returns size_t. As noted in the comments, use %zu to print it out.

Also, while(input[a]) will stop at the NULL terminator which means that your output will never hold a terminator and thus printf will keep on reading, you should add it at the end:

output[c] = '\0';

Also, as noted by @LPs in the comments, you should zero initialize the variables you work with :

 int a = 0, b = 0, c = 0;

Question 2: I have realized that I need a pretty large piece of memory allocated for the output to look as expected. strlen(input)*5 is an arbitrary number which seems to work, but why do I get seemingly 'random' errors when lowering the number?

Probably because you haven't allocated enough memory. Because the string length depends on runtime factors there's no way to know the exact memory needed you should allocate the maximum amount required:

char *output = malloc(strlen(input) * strlen(new) + 1);