简体   繁体   English

strncat()再次复制到相同的字符串

[英]strncat() is copying to the same string again

I am trying to concatenate two strings in C programming. 我正在尝试在C编程中连接两个字符串。 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. 当我尝试在s1打印值时,它会输出mv /home/xxxxxxx/.local/share/Trash作为输出。 Why is the value i am putting for s2 getting added with the string s1? 为什么我为s2输入的值与字符串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. 您的代码中没有未定义的行为 ,因为s1s2都没有初始化。 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. 未初始化(非静态)的局部变量具有不确定的值,并且它们不太可能具有strncat需要找到字符串末尾才能知道源字符串附加到何处的字符串终止符。

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. 解决上述问题之后,当strncat尝试将字符串终止符写入数组末尾时,您还会遇到另一种不确定行为的情况。

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. 另外,您没有将两个字符串连接在一起,因为s1s2是两个不相关的数组,您只需将文字字符串附加到两个数组的末尾即可,而不是一起。


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. 是否使用例如snprintf (或_snprintf使用Microsoft Windows运行时库)来构造字符串。

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. 当我尝试打印s1中的值时,它会输出mv /home/ashwini/.local/share/Trash作为输出。

This is undefined behavior: s1 is not null-terminated, because it has a three-character string in a space of three characters; 这是未定义的行为: s1不是以空字符结尾的,因为它在三个字符的空间中具有三个字符的字符串; 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 . 您的s2字符串缓冲区恰好位于内存的相邻区域中,因此它也将被打印,直到printf遇到s2的空终止符为止。

Allocating more memory to s1 and accounting for null termination would fix this problem: 将更多内存分配给s1并考虑空终止将解决此问题:

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. 但是, strncat不适用于常规字符串:它设计用于固定长度的字符串,而固定长度的字符串已不再广泛使用。 Unfortunately, C standard library does not include strlcat , which has proper semantic for "regular" C strings. 不幸的是,C标准库不包括strlcat ,它对“常规” C字符串具有适当的语义。 It is available on many systems as a library extension, though. 但是,它可以作为库扩展在许多系统上使用。

Demo. 演示

s1 is defined as s1定义为

char s1[3],

that is it has three elements (characters). 那就是它具有三个要素(字符)。 When strncat was executed 执行strncat

strncat(s1," mv",3);

this three elements were filled with { ' ', 'm', 'y' } 这三个元素都用{'','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. printf函数中的格式说明符%s输出一个字符数组,直到遇到终止符零为止。 As array s1 does not have the terminating zero then the printf continues to output all bytes that are beyond the array. 由于数组s1没有结尾的零,因此printf继续输出数组之外的所有字节。 because after array s1 there is array s2 因为在数组s1之后有数组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. 考虑到函数strncat要求目标字符串将以零终止。 However you did not initialize s1. 但是,您没有初始化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 如果希望程序正常运行,则必须将数组s1定义为具有四个字符

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 那是最好使用函数strcpy而不是strncpy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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