如何使用 strcat() 函数?

How to use strcat() function?

我对C语言很陌生。我正在尝试使用 strcat 函数。

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

int main(int argc, const char *argv[]) {
    char s1[] = "12345";
    char s2[] = "abcde";

    strcat(s1, s2);

    puts(s1);
    puts(s2);
    return 0;
}

这个运行正常,但是

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

int main(int argc, const char *argv[]) {
    char* s1 = "12345";
    char* s2 = "abcde";

    strcat(s1, s2);

    puts(s1);
    puts(s2);
    return 0;
}

最后一个没能return一个结果。为什么两种不同的声明方式 return 在 strcat 函数中产生不同的结果。提前致谢。

两个代码片段都调用了未定义的行为。在第一个片段中 s1 没有足够的 space 来容纳除六个字符之外的任何其他字符。
在第二个片段中,您试图修改字符串文字。任何修改字符串文字的尝试都会导致未定义的行为。

阅读strcat man page

[...] The strings may not overlap, and the dest string must have enough space for the result. If dest is not large enough, program behavior is unpredictable; buffer overruns are a favorite avenue for attacking secure programs.

在 C 中,函数 strcat 不会创建包含串联字符串的新字符数组。它将第二个字符串中的字符附加到第一个字符数组的第一个字符串中,前提是它有足够的元素来存储新字符。否则该函数将尝试覆盖超出字符数组的内存,从而导致未定义的行为。

所以第一个程序中函数的有效使用可以看下面的方式

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

int main(int argc, const char *argv[]) {
    char s1[11] = "12345";
    char s2[] = "abcde";

    strcat(s1, s2);

    puts(s1);
    puts(s2);
    return 0;
} 

在此程序中,字符数组被声明为具有 11 个元素。因此它能够容纳附加的字符串 "abcde".

在第二个程序中,试图修改指针 s1 指向的字符串文字。 C 和 C++ 中的字符串文字是不可变的。任何更改字符串文字的尝试都会导致未定义的行为,即使在与 C++ 相对的 C 中,字符串文字具有非常量字符数组类型。

来自 C 标准(6.4.5 字符串文字)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

所以在第二个程序中,您再次需要使用具有足够元素的字符数组。例如

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

int main(int argc, const char *argv[]) {
    char s1[11] = "12345";
    char* s2 = "abcde";

    strcat(s1, s2);

    puts(s1);
    puts(s2);
    return 0;
}

或者您可以使用可变长度数组 (VLA)(如果编译器支持)或动态分配数组。例如

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

int main(int argc, const char *argv[]) {
    char *s1 = "12345";
    char* s2 = "abcde";
    char s3[strlen( s1 ) + strlen( s2 ) + 1];    

    strcpy( s3, s1 );
    strcat( s3, s2 );

    puts(s1);
    puts(s2);
    puts(s3);

    return 0;
}

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

int main(int argc, const char *argv[]) {
    char *s1 = "12345";
    char* s2 = "abcde";
    char *s3 = malloc( strlen( s1 ) + strlen( s2 ) + 1 );    

    if ( s3 != NULL )
    {
        strcpy( s3, s1 );
        strcat( s3, s2 );

        puts(s1);
        puts(s2);
        puts(s3);
    }

    free( s3 );

    return 0;
}