56 votes

C string append

Je veux ajouter deux chaînes de caractères. J'ai utilisé la commande suivante :

new_str = strcat(str1, str2);

Cette commande modifie la valeur de str1 . Je veux new_str pour être la concaténation de str1 y str2 et en même temps str1 ne doit pas être modifié.

5 votes

Vous avez raison, c'est ce qu'il fait.

2 votes

Pour diverses raisons, vous pourriez vouloir garder une trace des tailles de str1 , str2 y new_str et utiliser strncat au lieu de simplement strcat ). Cela permettra d'éviter certaines erreurs de dépassement de tampon.

79voto

Charlie Martin Points 62306

Vous devez également allouer un nouvel espace. Considérez ce fragment de code :

char * new_str ;
if((new_str = malloc(strlen(str1)+strlen(str2)+1)) != NULL){
    new_str[0] = '\0';   // ensures the memory is an empty string
    strcat(new_str,str1);
    strcat(new_str,str2);
} else {
    fprintf(STDERR,"malloc failed!\n");
    // exit?
}

Vous pouvez envisager strnlen(3) ce qui est légèrement plus sûr.

Mise à jour de voir ci-dessus. Dans certaines versions du runtime C, la mémoire retournée par malloc n'est pas initialisé à 0. En mettant le premier octet de new_str à zéro assure que cela ressemble à une chaîne vide pour strcat.

14 votes

malloc peut toujours renvoyer des déchets, et il le fait même sur les systèmes modernes. calloc vous donne une mémoire nulle.

2 votes

Et calloc prend aussi souvent du temps sizeof(space) pour le faire. Si vous faites beaucoup de chaînes de caractères et que vous êtes prudent avec vos pointeurs, vous pouvez économiser beaucoup d'instructions redondantes.

2 votes

Veuillez retirer la conjecture incorrecte : "Je crois que la nouvelle spécification C exige que malloc le fasse". De plus, le fait de mettre le premier octet à zéro en fait une chaîne de longueur nulle par définition (et non par apparence).

13voto

VirtualTroll Points 1705

Faites ce qui suit :

strcat(new_str,str1);
strcat(new_str,str2);

7 votes

Avec la réserve que new_str doit être initialisé à une chaîne vide.

2 votes

Cela se bloque lorsque new_str ne peut pas contenir l'espace ou (*new_str) != 0

2 votes

Ça me donne toujours "erreur de segmentation".

7voto

Envisagez d'utiliser la grande mais inconnue fonction open_memstream().

FILE *open_memstream(char **ptr, size_t *sizeloc);

Exemple d'utilisation :

// open the stream
FILE *stream;
char *buf;
size_t len;
stream = open_memstream(&buf, &len);

// write what you want with fprintf() into the stream
fprintf(stream, "Hello");
fprintf(stream, " ");
fprintf(stream, "%s\n", "world");

// close the stream, the buffer is allocated and the size is set !
fclose(stream);
printf ("the result is '%s' (%d characters)\n", buf, len);
free(buf);

Si vous ne connaissez pas à l'avance la longueur de ce que vous voulez ajouter, c'est plus pratique et plus sûr que de gérer vous-même les tampons.

1voto

Joel Falcou Points 3791

Vous devrez strncpy str1 en new_string d'abord alors.

0voto

Wei Points 11

J'écris une fonction supportant la variable dynamique string append, comme PHP str append : str + str + ... etc.

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

int str_append(char **json, const char *format, ...)
{
    char *str = NULL;
    char *old_json = NULL, *new_json = NULL;

    va_list arg_ptr;
    va_start(arg_ptr, format);
    vasprintf(&str, format, arg_ptr);

    // save old json
    asprintf(&old_json, "%s", (*json == NULL ? "" : *json));

    // calloc new json memory
    new_json = (char *)calloc(strlen(old_json) + strlen(str) + 1, sizeof(char));

    strcat(new_json, old_json);
    strcat(new_json, str);

    if (*json) free(*json);
    *json = new_json;

    free(old_json);
    free(str);

    return 0;
}

int main(int argc, char *argv[])
{
    char *json = NULL;

    str_append(&json, "name: %d, %d, %d", 1, 2, 3);
    str_append(&json, "sex: %s", "male");
    str_append(&json, "end");
    str_append(&json, "");
    str_append(&json, "{\"ret\":true}");

    int i;
    for (i = 0; i < 10; i++) {
        str_append(&json, "id-%d", i);
    }

    printf("%s\n", json);

    if (json) free(json);

    return 0;
}

0 votes

Cette solution serait très inefficace très rapide

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X