2012-04-23 13 views
29

Wie füge ich ein einzelnes Zeichen an eine Zeichenfolge in C an?Char an String in C anhängen?

d.h

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

Mit der Maßgabe, dass Ihre Definition eines Strings in Zeile 1 ein Char-Array mit genügend Speicher zugewiesen sein muss (wie in den Antworten beschrieben), versuchen Sie strncat (str, &c,1); für das tatsächliche Anhängen. –

Antwort

4

ich Sie nicht denken, eine Zeichenfolge wie in c erklären kann. Sie können das nur für const char * tun und natürlich können Sie ein const char * nicht ändern, da es const ist.

Sie können dynamische char-Array verwenden, aber Sie müssen sich um die Neuzuweisung kümmern.

EDIT: in der Tat kompiliert diese Syntax korrekt. Dennoch kann man nicht ändern, welche Punkte str wenn es in der Art und Weise initialisiert Sie es tun (von Stringliteral)

+1

'char * ptr =" string "' ist perfekt in C gültig. –

+1

@Als - ja, das stimmt. Ich dachte, es ist nicht, aber es scheint, es ist in Ordnung. Sie können das Array jedoch immer noch nicht ändern. –

+1

Ja, Sie können das * String-Literal * nicht ändern, es ist kein Array, mit dem Sie beginnen möchten. –

22

Um ein Zeichen in eine Zeichenfolge in C anhängen, müssen Sie zunächst sicherstellen, dass der Pufferspeicher mit der Zeichenfolge groß genug ist, um ein zusätzliches Zeichen zu empfangen. In Ihrem Beispielprogramm müssen Sie einen neuen, zusätzlichen Speicherblock zuweisen, da die angegebene Literalzeichenfolge nicht geändert werden kann.

Hier ist ein Beispiel:

#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); 
} 

Verwenden Sie zuerst malloc einen neuen Teil des Speichers zuzuweisen, die groß genug ist, um alle Zeichen der Eingabezeichenfolge zu empfangen, die zusätzliche Zeichen anzuhängen - und die letzte Null. Rufen Sie dann strcpy auf, um die Eingabezeichenfolge in den neuen Puffer zu kopieren. Schließlich ändern Sie die letzten zwei Bytes im neuen Puffer, um das hinzuzufügende Zeichen und die nachfolgende Null anzuheften.

+0

Der Kommentar zur Verwendung von sizeof ist falsch. 'sizeof str' ist entweder 4 oder 8, abhängig davon, ob Sie 32- oder 64-Bit-Code kompilieren. – JeremyP

+0

Verwenden Sie in printf auch immer einen Formatspezifizierer. Stellen Sie sich vor, wenn 'str' eine '% s'-Char-Sequenz enthält. – JeremyP

+0

@ JeremyP Der 'sizeof' Kommentar ist in der Tat ungenau. Ich meinte, dass Sie 'sizeof (" blablablah ") nennen können. Ich werde den Kommentar einfach komplett entfernen, da der Compiler möglicherweise schlau genug ist, um zu bemerken, dass er den Aufruf ständig falten kann. Was den Formatbezeichner betrifft - Sie haben natürlich Recht, ein sehr peinlicher Fehler. Ich werde meine Antwort aktualisieren. –

1

C hat keine Zeichenketten per se - was Sie haben, ist ein Zeichenzeiger, der auf einen schreibgeschützten Speicher zeigt, der die Zeichen "blablabla \ 0" enthält. Um ein Zeichen dort anzufügen, benötigen Sie a) beschreibbaren Speicher und b) genügend Platz für die Zeichenfolge in ihrer neuen Form. Das String-Literal "blablabla \ 0" hat keines.

Die Lösungen sind:

1) Verwenden malloc() et al. um Speicher dynamisch zuzuweisen. (Vergessen Sie danach nicht free().)
2) Verwenden Sie ein Char-Array.

Wenn Sie mit Strings arbeiten, sollten Sie strn* Varianten der str* Funktionen in Betracht ziehen - sie werden Ihnen helfen, innerhalb des Speicherbereichs zu bleiben.

+1

Verwenden Sie niemals 'strncpy'. Es ist keine String-Funktion (trotz seines Namens) und verursacht nur Probleme. – melpomene

-3

hier ist es, es funktioniert 100%

char* appending(char *cArr, const char c) 

{ 

int len = strlen(cArr); 

cArr[len + 1] = cArr[len]; 

cArr[len] = c; 

return cArr; 


} 
+2

Das funktioniert nur, wenn der String, auf den "cArr" zeigt, beschreibbar * und * ist, wenn genügend Platz zum Hinzufügen eines anderen Zeichens vorhanden ist. –

+7

-1, da es nur "100%" für sehr kleine Werte von "100" funktioniert. –

2

Der einfachste Weg, zwei Strings anhängen:

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

Wenn Sie die Nicht-Standard-'Asprintf'-Funktion haben; Es ist weder durch die C-Sprache noch durch POSIX definiert. –

+0

Liefern Sie nicht einen Verweis auf lokale Variable? – Abhishek

+0

Ich hatte nie ein Problem damit, vielleicht ashprintf reserviert den Speicher. –

2

Erstellen Sie eine neue Zeichenfolge (string + char)

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

Ändern Sie nicht die Array-Größe ([len +1], etc.) ohne es zu wissen s genaue Größe, kann es andere Daten beschädigen. alloc ein Array mit der neuen Größe und setzen Sie stattdessen die alten Daten, denken Sie daran, dass für ein Char-Array der letzte Wert \0 sein muss; calloc() setzt alle Werte auf \0, was für char Arrays hervorragend ist.

Ich hoffe, das hilft.

2

Das Originalplakat bedeuten nicht, schreiben:

char* str = "blablabla"; 

aber

char str[128] = "blablabla"; 

nun ein einzelnes Zeichen Zugabe effizienter scheint als eine ganze Reihe mit strcat hinzufügen. den strcat Weg gehen, könnten Sie:

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

aber Sie können Ihre eigene Funktion auch einfach schreiben (wie einige vor mir getan haben):

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

In meinem Fall ist dies die beste Lösung ich fand:

snprintf(str, sizeof str, "%s%c", str, c); 
+0

Das sieht für mich wie undefiniertes Verhalten aus. Ich glaube nicht, dass Sie das Zielargument 'str' als eines der Argumente des Formatstrings (' "% s ...", str, ... ') übergeben dürfen. – melpomene

-4

in C++, Sie können einfach eine char zu einem hinzufügen string von:

int main() 
{ 
    std::string s = "Hello there"; 
    char c = '?'; 
    s = s+c; 
    std::cout << s << std::endl; 
    return 0; 
} 
+1

Das ist C++, nicht C. – melpomene