在C语言中如何将字符添加到字符串中?

61

如何在C语言中将一个单个字符追加到字符串末尾?

例如:

char* str = "blablabla";
char c = 'H';
str_append(str,c); /* blablablaH */

在第一行中,假设您对字符串的定义是一个已分配足够内存的字符数组(如答案中所述),请尝试使用strncat(str,&c,1)进行实际的追加。 - Chris Johnson
12个回答

44

在C语言中向字符串追加字符,您首先必须确保包含字符串的内存缓冲区足够大以容纳额外的字符。在您的示例程序中,您需要分配一个新的附加内存块,因为给定的字面字符串是不可修改的。

这里是一个示例:

#include <stdlib.h>

int main()
{
    char *str = "blablabla";
    char c = 'H';

    size_t len = strlen(str);
   
    /* one for extra char, one for trailing zero */
    char *str2 = malloc(len + 1 + 1);

    strcpy(str2, str);
    str2[len] = c;
    str2[len + 1] = '\0';

    printf("%s\n", str2); /* prints "blablablaH" */

    free(str2);
}

首先使用malloc分配一个新的内存块,该块足以容纳输入字符串中的所有字符、追加的额外字符和最后的零。然后调用strcpy将输入字符串复制到新缓冲区中。最后,更改新缓冲区中的最后两个字节以附加要添加的字符以及尾随的零。


关于使用sizeof的评论是不正确的。sizeof str取决于您编译32位或64位代码,它可能是4或8。 - JeremyP
此外,在 printf 中始终使用格式说明符。想象一下,如果 str 中包含一个 %s 字符序列。 - JeremyP
@JeremyP,“sizeof”注释确实不够精确。我的意思是你可以调用sizeof("blablablah"),我将完全删除该注释,因为编译器可能足够聪明,能够const-fold调用。至于格式说明符-当然,这是一个非常尴尬的错误。我会更新我的答案。 - Frerich Raabe

43

7
原帖作者的本意并不是写下这个:
  char* str = "blablabla";

但是
  char str[128] = "blablabla";

现在,添加单个字符似乎比使用strcat添加整个字符串更有效率。 如果使用strcat方法,您可以:

  char tmpstr[2];
  tmpstr[0] = c;
  tmpstr[1] = 0;
  strcat (str, tmpstr);

但是你也可以很容易地编写自己的函数(就像我之前的一些人所做的那样):

  void strcat_c (char *str, char c)
  {
    for (;*str;str++); // note the terminating semicolon here. 
    *str++ = c; 
    *str++ = 0;
  }

6

如果您关注Linux,最简单的方法是将两个字符串拼接起来:

char * append(char * string1, char * string2)
{
    char * result = NULL;
    asprintf(&result, "%s%s", string1, string2);
    return result;
}

这将无法在MS Visual C中工作。

注意: 你必须通过free()函数释放由asprintf()函数返回的内存。


4
如果你有非标准的asprintf函数,那么它既不是C语言也不是POSIX定义的。 - Keith Thompson
你不是在返回一个局部变量的引用吗? - Abhishek
我从来没有遇到过这个问题,也许是asprintf分配了内存。 - Lay González
4
@Abhishek 的 asprintf 函数会动态分配足够的空间以容纳结果字符串。显然,它可用于 GNU glibc 和大多数 BSD 版本(将 OS X 视为 BSD 的一种版本)。 - JeremyP

4

我认为在C语言中不能像那样声明字符串。你只能对const char *这样做,当然,你不能修改const char *,因为它是常量。

你可以使用动态char数组,但你需要注意重新分配内存。

编辑:事实上,这种语法可以正确编译。但如果str是通过字符串字面量初始化的,则不应该修改它指向的内容。


2
在C语言中,char *ptr = "string"是完全有效的。 - Alok Save
1
@Als - 是的,没错。我原以为不行,但看起来是可以的。然而你仍然不能修改数组。 - Ivaylo Strandjev
2
是的,您无法修改字符串字面量,因为它本来就不是一个数组。 - Alok Save
@Als 再次同意 - 这是一个字面意思 :) - Ivaylo Strandjev
1
@AlokSave 字符串字面量是数组。 - melpomene

4
创建一个新的字符串(字符串 + 字符)。
#include <stdio.h>    
#include <stdlib.h>

#define ERR_MESSAGE__NO_MEM "Not enough memory!"
#define allocator(element, type) _allocator(element, sizeof(type))

/** Allocator function (safe alloc) */
void *_allocator(size_t element, size_t typeSize)
{
    void *ptr = NULL;
    /* check alloc */
    if( (ptr = calloc(element, typeSize)) == NULL)
    {printf(ERR_MESSAGE__NO_MEM); exit(1);}
    /* return pointer */
    return ptr;
}

/** Append function (safe mode) */
char *append(const char *input, const char c)
{
    char *newString, *ptr;

    /* alloc */
    newString = allocator((strlen(input) + 2), char);
    /* Copy old string in new (with pointer) */
    ptr = newString;
    for(; *input; input++) {*ptr = *input; ptr++;}
    /* Copy char at end */
    *ptr = c;
    /* return new string (for dealloc use free().) */
    return newString;
}

/** Program main */
int main (int argc, const char *argv[])
{
    char *input = "Ciao Mondo"; // i am italian :), this is "Hello World"
    char c = '!';
    char *newString;

    newString = append(input, c);
    printf("%s\n",newString);
    /* dealloc */
    free(newString);
    newString = NULL;

    exit(0);
}

              0   1   2   3    4    5   6   7   8   9  10   11
newString is [C] [i] [a] [o] [\32] [M] [o] [n] [d] [o] [!] [\0]

不要更改数组的大小(如[len+1]等),除非您确切知道其大小,否则可能会损坏其他数据。使用新大小为数组alloc并将旧数据放入其中,记住,对于字符数组,最后一个值必须是\0; calloc()将所有值设置为\0,这对于char数组非常好。
希望这能帮到您。

3

您可以使用string.h标准头文件中的strcat函数,但请不要将char作为第二个参数传递,而应改用以下代码:

void append_str(char str[] , char c){
     auto char arr[2] = {c , '\0'};
     strcat(str , arr);
}

2

C语言本身并没有字符串的概念——你所拥有的是一个指向只读内存的char指针,其中包含字符“blablabla\0”。为了在这里追加一个字符,你需要a)可写内存和b)足够的空间,以使字符串呈其新形式。而字符串文字“blablabla\0”两者都没有。

解决方案如下:

1)使用malloc()等动态分配内存。(别忘了在使用后使用free()。)
2)使用char数组。

在处理字符串时,请考虑使用strn*变体的str*函数—它们将帮助您保持在内存边界内。


1
但是永远不要使用strncpy。尽管它的名字是字符串函数,但它只会带来麻烦。 - melpomene

2
您可以使用strncat()函数。
#include <stdio.h>
#include <string.h>

int main(void){
  char hi[6];
  char ch = '!';
  strcpy(hi, "hello");

  strncat(hi, &ch, 1);
  printf("%s\n", hi);
}

0

您可以使用strncat()函数,将其指针指向您的字符(但首先请检查缓冲区是否足够大以存储结果字符串):

char myString[100] = "Feli";
char toAppend = 'x';
// do something here to check if the buffer is large enough...
strncat(myString, &toAppend, 1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接