0

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
programmer
  • 39
  • 7
  • 4
    [strncpy man page says](http://linux.die.net/man/3/strncpy): "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. – kaylum Nov 29 '15 at 22:51
  • There are many problems with this code, such as memory leaks, casting the result of `malloc` (it's a disease), and bad formatting. What is the purpose of the `k` and `i` variables? Because they're the main cause of this issue. – user4520 Nov 29 '15 at 22:59
  • 1
    stop using `strncpy`. Use `snprintf` instead – M.M Nov 30 '15 at 02:14
  • `char s[lens+1];` is simpler than all that malloc garble – M.M Nov 30 '15 at 02:15
  • @kaylum thank you so much so i have to add result[k]='\0' just after the instruction strncpy ? it should work fine – programmer Nov 30 '15 at 22:49
  • @szczurcio i'm open to any solutions or suggestions, thank you – programmer Nov 30 '15 at 22:51
  • @M.M can i have an exemple of snprintf please – programmer Nov 30 '15 at 22:58
  • `snprintf(result, n, "%.*s%s%s", k, s1, s2+i, s1+k);` . It'd also be a good idea to validate that `i` and `k` are not past the end of `s2` and `s1` – M.M Nov 30 '15 at 23:01

2 Answers2

6

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.
kaylum
  • 13,833
  • 2
  • 22
  • 31
0

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);
}
autistic
  • 1
  • 3
  • 35
  • 80