I have experienced an issue while using strcat, using realloc however, strcat overwrites destination string
char *splitStr(char *line) {
char *str_;
str_ = (char *) malloc(1);
char *ptr = strtok(line,"\n");
int a;
while (ptr != NULL) {
if (ptr[0] != '$') {
printf("oncesi %s\n", str_);
a = strlen(ptr) + strlen(str_) + 1;
str_ = realloc(str_, a);
strcat(str_, ptr);
str_[a] = '\0';
printf("sontasi:%s\n", str_);
}
ptr = strtok(NULL, "\n");
}
printf("splitStr %d\n", strlen(str_));
printf("%s", str_);
return str_;
}
and my input value is ;
*4
$3
200
$4
4814
$7
SUCCESS
$4
3204
so I want to split this input value via strtok; strtok(line,'\n');
and concat all line without start "$" char to new char. However, this code give following output;
line: *4
oncesi
sontasi:*4
oncesi *4
200tasi:*4
200esi *4
4814asi:*4
4814si *4
SUCCESS:*4
SUCCESS*4
3204ESS:*4
splitStr 25
seems to overwrite source string. do you have any idea why this issue could be happening ?
the following proposed code:
malloc()
and realloc()
strlen()
returns a size_t
, not an int
. so the proper output format conversion specifier is: %zu
and now, the proposed code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char *splitStr( char *line )
{
printf("original line: %s\n", line);
char *str = malloc(1);
if( !str )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
str[0] = '\0'; // critical statement
char *token = strtok(line,"\n");
while( token )
{
if( token[0] != '$')
{
char* temp = realloc( str, strlen( token ) + strlen( str ) + 1 );
if( ! temp )
{
perror( "realloc failed" );
free( str );
exit( EXIT_FAILURE );
}
str = temp; // update pointer
strcat(str, token);
printf( "concat result: %s\n", str );
}
token = strtok(NULL, "\n");
}
printf("splitStr %zu\n", strlen(str));
return str;
}
int main( void )
{
char firstStr[] = "$abcd\n$defg\nhijk\n";
char *firstNewStr = splitStr( firstStr );
printf( "returned: %s\n\n\n\n", firstNewStr );
free( firstNewStr );
char secondStr[] = "abcd\ndefg\nhijk\n";
char *secondNewStr = splitStr( secondStr );
printf( "returned: %s\n\n\n\n", secondNewStr );
free( secondNewStr );
}
a run of the proposed code results in:
original line: $abcd
$defg
hijk
concat result: hijk
splitStr 4
returned: hijk
original line: abcd
defg
hijk
concat result: abcd
concat result: abcddefg
concat result: abcddefghijk
splitStr 12
returned: abcddefghijk