programmer
programmer

Reputation: 39

strncpy and strcat garbage characters in C

I tried to write a programme which copies the first k char from a string s1 and then concatenates the result with the rest of string s2 starting from a position i then concatenates the rest of s1 in the result. Yet I had some problems with strncpy. It shows some weird characters in console like @.

Here's my code:

char* strninsert(char *s1, char *s2, int k,int i)
{
    int n=strlen(s1)+strlen(s2)+10; // if i put for exemple 1000 it works
    char *result=(char*)malloc(n*sizeof(char));
    result[0]='\0';
    strncpy(result,s1,k);
    strcat(result,(s2+i));
    strcat(result,(s1+k));
    puts(result);
    return(result);
}

int main()
{
    int lens;
    printf("size string 1 ");
    scanf("%d",&lens);
    char *s=(char*)malloc((lens+1)*sizeof(char));
    getchar();
    fgets(s,lens+1,stdin);

    int lenx;
    printf("enter size string 2 ");
    getchar();
    scanf("%d",&lenx);
    char *x=(char*)malloc((lenx+1)*sizeof(char));
    getchar();
    fgets(x,lenx+1,stdin);

    int lentemp=lenx+lens;
    char *temp=(char*)malloc((lentemp+1)*sizeof(char));

    temp=strninsert(s,x,2,3);
    puts(temp);
    return(0);
}

It shows me weird characters after the strncpy instruction like for example poes@<line.

Upvotes: 0

Views: 1472

Answers (2)

autistic
autistic

Reputation: 15632

As previously answered by kaylum, the result of strncpy is not necessarily a string. This poses a hazard when passing it to strcat, as strcat requires that both arguments definitively be a string.

The nicest solution to your problem I can think of involves using sprintf, like so:

void solution(char *destination, char *x, int x_size, char *y) {
    sprintf(destination, "%*.s%s", x_size, x, y);
}

Upvotes: 0

kaylum
kaylum

Reputation: 14046

strncpy man page says:

Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

That is, if the value k in your code is less than strlen(s1)+1 then the resulting contents in result will not be NUL terminated. One possible fix is to change your code thus:

/* Sanity check. */
if (k > strlen(s1)) {
    k = strlen(s1);
}

strncpy(result , s1, k);
result[k] = '\0';

Also, not directly related to your problem but you have memory leaks in your code.

  1. In main the temp variable received a malloc buffer which is then immediately lost as temp is overwritten by the strninsert result.
  2. The result of strninsert is dynamic memory which is not freed anywhere.

Upvotes: 6

Related Questions