web-dev-qa-db-fra.com

Ajouter un caractère à la chaîne en C?

Comment ajouter un seul caractère à une chaîne en C?

c'est à dire

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

Vous ne devriez pas modifier cette chaîne du tout. Il réside dans la région en lecture seule définie par l'implémentation. Le modifier provoque un comportement non défini .

Vous avez besoin d'un tableau de caractères et non d'un littéral de chaîne.

Bonne lecture:
Quelle est la différence entre char a [] = "chaîne"; et char * p = "chaîne";

32
Alok Save

Pour ajouter un caractère à une chaîne en C, vous devez d'abord vous assurer que la mémoire tampon contenant la chaîne est suffisamment grande pour accueillir un caractère supplémentaire. Dans votre exemple de programme, vous devez allouer un nouveau bloc de mémoire supplémentaire car la chaîne littérale donnée ne peut pas être modifiée.

Voici un exemple:

#include <stdlib.h>

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

    size_t len = strlen(str);
    char *str2 = malloc(len + 1 + 1 ); /* one for extra char, one for trailing zero */
    strcpy(str2, str);
    str2[len] = c;
    str2[len + 1] = '\0';

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

    free( str2 );
}

Commencez par utiliser malloc pour allouer un nouveau bloc de mémoire suffisamment volumineux pour accueillir tous les caractères de la chaîne d'entrée, le caractère supplémentaire à ajouter - et le zéro final. Ensuite, appelez strcpy pour copier la chaîne d'entrée dans le nouveau tampon. Enfin, changez les deux derniers octets dans le nouveau tampon pour ajouter le caractère à ajouter, ainsi que le zéro final.

34
Frerich Raabe

Je ne pense pas que vous puissiez déclarer une telle chaîne dans c. Vous ne pouvez le faire que pour const char * et vous ne pouvez bien sûr pas modifier un const char * car il est const.

Vous pouvez utiliser un tableau de caractères dynamique, mais vous devrez vous occuper de la réaffectation.

EDIT: en fait, cette syntaxe est compilée correctement. Néanmoins, vous ne pouvez pas modifier ce sur quoi pointe str s'il est initialisé de la façon dont vous le faites (à partir du littéral de chaîne)

4
Ivaylo Strandjev

Le moyen le plus simple d’ajouter deux chaînes:

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

Créer une nouvelle chaîne (chaîne + caractère)

#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]

Ne modifiez pas la taille du tableau ([len +1], Etc.) sans connaître sa taille exacte, cela pourrait endommager d'autres données. alloc un tableau de la nouvelle taille contenant les anciennes données, rappelez-vous que pour un tableau de caractères, la dernière valeur doit être \0; calloc() définit toutes les valeurs sur \0, ce qui est excellent pour les tableaux char.

J'espère que ça aide.

2
AlfioSoft

L’affiche originale ne voulait pas écrire:

  char* str = "blablabla";

mais

  char str[128] = "blablabla";

Maintenant, ajouter un seul caractère semblerait plus efficace que d'ajouter une chaîne entière avec strcat. En suivant le chemin, vous pourriez:

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

mais vous pouvez aussi écrire facilement votre propre fonction (comme plusieurs l'ont fait avant moi):

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

C n’a pas de chaîne en tant que telle - ce que vous avez est un pointeur de caractère pointant vers une mémoire en lecture seule contenant les caractères "blablabla\0". Pour y ajouter un caractère, il vous faut a) une mémoire inscriptible et b) un espace suffisant pour la chaîne dans sa nouvelle forme. Le littéral de chaîne "blablabla\0" n'a ni l'un ni l'autre.

Les solutions sont:

1) Utilisez malloc() et al. allouer dynamiquement de la mémoire. (N'oubliez pas de free() après.)
2) Utilisez un tableau de caractères.

Lorsque vous travaillez avec des chaînes, pensez à utiliser strn* variantes du str* _ fonctions - ils vous aideront à rester dans les limites de la mémoire.

1
aib