简体   繁体   中英

strncat() is copying to the same string again

I am trying to concatenate two strings in C programming. Here is my code:

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

int main(int argc, char const *argv[])
{
    /* code */
        char s1[3],s2[34];

        strncat(s1,"mv ",3);
        strncat(s2,"  /home/xxxxxxx/.local/share/Trash/",34);

        printf("%s \n",s1);

        return 0;

}

when I try to print the value in s1 it prints mv /home/xxxxxxx/.local/share/Trash as the output. Why is the value i am putting for s2 getting added with the string s1? If the question is already asked please put the link.

You have undefined behavior in your code, as neither s1 nor s2 are initialized. Uninitialized (non-static) local variables have indeterminate values, and it's unlikely that they have the string terminator that strncat needs to find the end of the string to know where to append the source string.

After you fix the above, you also have another case of undefined behavior when strncat tries to write the string terminator beyond the end of the arrays.

Also, you're not concatenating the two strings, as s1 and s2 are two unrelated arrays, you just append the literal strings to the end of the two arrays but not together.


What you could do is to allocate an array big enough to hold both strings, and the string terminator, then copy the first string into the array, and then append the second string.

Or not use eg snprintf (or _snprintf is using the Microsoft Windows runtime library) to construct the string.

char s[100];
snprintf(s, sizeof(s), "mv %s %s", somepath, someotherpath);

when I try to print the value in s1 it prints mv /home/ashwini/.local/share/Trash as the output.

This is undefined behavior: s1 is not null-terminated, because it has a three-character string in a space of three characters; there's no space for the null terminator.

Your s2 string buffer happens to be located in the adjacent region of memory, so it gets printed as well, until printf runs into the null terminator of s2 .

Allocating more memory to s1 and accounting for null termination would fix this problem:

char s1[4],s2[36];
s1[0] = '\0';
strncat(s1," mv", 4);
s2[0] = '\0';
strncat(s2,"  /home/xxxxxxx/.local/share/Trash/", 36);

However, strncat is not a proper function for working with regular strings: it is designed for use with fixed-length strings, which are no longer in widespread use. Unfortunately, C standard library does not include strlcat , which has proper semantic for "regular" C strings. It is available on many systems as a library extension, though.

Demo.

s1 is defined as

char s1[3],

that is it has three elements (characters). When strncat was executed

strncat(s1," mv",3);

this three elements were filled with { ' ', 'm', 'y' }

After that this array does not have the terminating zero.

Format specifier %s in printf function outputs a character array until the terminatig zero will be encountered. As array s1 does not have the terminating zero then the printf continues to output all bytes that are beyond the array. because after array s1 there is array s2

char s1[3],s2[34];

then it also is outputed until the terminating zero will be encountered.

Take into account that function strncat requires that the target string would be zero terminated. However you did not initialize s1. So the behaviour of the program is undefined.

If you want that the program would work correctly you have to define array s1 as having four characters

char s1[4] = { '\0' },s2[34];

strncat(s1,"mv ",4);

Or it would be simpler to write

char s1[4] = { '\0' },s2[34];

strcat( s1, "mv " );

Or even the following way

char s1[4],s2[34];

strcpy( s1, "mv " );

that is it would be better to use function strcpy instead of strncpy

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM