2017-07-28 39 views
0

我是C语言的新手。我试图使用strcat函数。如何使用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; 
} 

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

+3

庆典 - >男人的strcat – Jonas

+2

你似乎相信它分配它所需要的内存。那么,它不会。 – Siguza

+5

这两种都是未定义的行为。 – BLUEPIXY

回答

5

在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这些阵列是否是不同的条件是它们的 元素具有适当的值是不确定的。 如果程序尝试 修改这样一个数组,行为是未定义的。

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

#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; 
} 
+0

海事组织,备用语言讨论(C++)减损,特别是对于“我是非常新的C”OP,从这个美好的C回答中,。建议删除或将备用语言讨论移到答案的后面部分。 – chux

+0

谢谢你的回答和你的耐心。 – zyx

+0

@zyx根本没有。不用谢。 –

7

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

阅读strcat man page

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

+0

以下所有内容都是“更好的”:Linux:http://man7.org/linux/man-pages/man3/strcat.3.html,Linux/POSIX:http://man7.org/linux/man-pages /man3/strcat.3p.html,POSIX:http://pubs.opengroup.org/onlinepubs/9699919799/functions/strcat.html,C11-Standard:http://port70.net/~nsz/c/c11/ n1570.html#7.24.3.1然后这个“* linux.die.net *”垃圾邮件的东西...不是吗? – alk

+2

@alk;改变了它。顺便说一句,为什么它是垃圾邮件? – haccks

+0

您的浏览器是否会筛选出所有这些页面正在传递给我的桌面? – alk