如何使用strcat()函数?

zyx*_*zyx 2 c string pointers c-strings strcat

我是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;
}
Run Code Online (Sandbox Code Playgroud)

这个正常运行,但是

#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;
}
Run Code Online (Sandbox Code Playgroud)

最后一个未能返回结果.为什么两种不同的声明方式在strcat函数中返回不同的结果.提前致谢.

hac*_*cks 8

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

阅读strcat手册页:

[...]字符串可能不重叠,dest字符串必须有足够的空间用于结果.如果dest不够大,程序行为是不可预测的; 缓冲区溢出是攻击安全程序的最佳途径.

  • @alk; 改变了.顺便说一句,为什么它是垃圾邮件? (2认同)

Vla*_*cow 6

在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;
} 
Run Code Online (Sandbox Code Playgroud)

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

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

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

7如果这些数组的元素具有适当的值,则这些数组是否不同是未指定的.如果程序试图修改此类数组,则行为未定义.

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

或者,如果编译器支持可变长度数组(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;
}
Run Code Online (Sandbox Code Playgroud)

要么

#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;
}
Run Code Online (Sandbox Code Playgroud)