2012-04-23 17 views
29

Cの文字列に単一の文字を追加するにはどうすればよいですか?文字をCの文字列に追加しますか?

すなわち

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

ただし、1行目の文字列の定義は、十分なメモリが割り当てられているchar配列でなければなりません(実際の追加についてはstrncat(str、&c,1);)。 –

答えて

24
char* str = "blablabla";  

を何strのポイントを変更しないでくださいすることができます。実装定義の読み取り専用領域に存在します。それを変更すると、未定義の動作が発生します。

文字列リテラルではなく、char配列が必要です。

グッド読む:
What is the difference between char a[] = "string"; and char *p = "string";

4

私はあなたがC言語でそのような文字列を宣言することができるとは思いません。あなたはconst char *に対してのみ行うことができます。もちろん、const char *をconstとして変更することはできません。

動的な文字配列を使用できますが、再割り当てが必要です。

EDIT:実際この構文は正しくコンパイルされます。それでもあなたは、あなたがすべてでこの文字列を変更してはなりません(文字列リテラルから)それはあなたがそれを行う方法で初期化されている場合に

+1

'char * ptr =" string "'はCで完全に有効です。 –

+1

@Als - そうです。私はそれがないと思ったが、それは大丈夫だと思われる。しかし、まだ配列を変更することはできません。 –

+1

はい、*文字列リテラルを変更することはできません。*これは配列ではありません。 –

22

Cの文字列に文字を追加するには、最初の文字列を含むメモリバッファは、余分な文字を収容するのに十分な大きさであることを確認する必要があります。あなたのサンプルプログラムでは、与えられたリテラル文字列を変更することができないので、新しい追加メモリブロックを割り当てる必要があります。 - 最終的なゼロファースト

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

、余分な文字を追加する入力文字列のすべての文字を収容するのに十分な大きさのメモリの新しいチャンクを割り当てるmallocを使用します。

は、ここでのサンプルです。次に、strcpyを呼び出して、入力ストリングを新しいバッファーにコピーします。最後に、新しいバッファの最後の2バイトを、追加する文字と末尾のゼロを指すように変更します。

+0

sizeofの使用に関するコメントが間違っています。 'sizeof str'は32ビットか64ビットのどちらのコードをコンパイルするかによって4または8のいずれかです。 – JeremyP

+0

また、常にprintfに書式指定子を使用してください。 'str'に'%s'文字列が含まれているとします。 – JeremyP

+0

@JeremyP 'sizeof'コメントは確かに不正確です。私は 'sizeof(" blablablah ")'を呼び出すことができるということを意味しました。コンパイラが呼び出しをconst-foldできることに気付くほどスマートなので、コメントをすべて削除します。フォーマット指定子に関しては、あなたは間違いなく、非常に厄介なエラーです。私は私の答えを更新します。 –

1

Cには文字列自体がありません - あなたが持っているものは、 "blablabla \ 0"という文字を含む読み取り専用メモリを指す文字ポインタです。そこに文字を追加するには、a)書込み可能なメモリとb)文字列の新しい形のスペースが必要です。文字列リテラル "blablabla \ 0"にはいずれもありません。

溶液である:

1)malloc()ら使用します。動的にメモリを割り当てる。 (後でfree()に忘れないでください)
2)char配列を使用します。

文字列を操作するときは、str*のバリアントのstrn*を使用することをお勧めします。これらのバリアントは、メモリの境界内にとどまるのに役立ちます。

+1

しかし、 'strncpy'を使用しないでください。これは文字列関数ではなく(名前にもかかわらず)、問題を引き起こすだけです。 – melpomene

-3

ここで、それはだ、それは二つの文字列追加する100%

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

{ 

int len = strlen(cArr); 

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

cArr[len] = c; 

return cArr; 


} 
+2

'cArr'が指す文字列が書き込み可能である場合にのみ機能し、別の文字を追加するのに十分な余裕がある場合は*です。 –

+7

-1 "100"という非常に小さな値に対しては "100%"しか働かないためです。 –

2

最も簡単な方法WORKS:新しい文字列(文字列+文字)を作成します

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

非標準の 'asprintf'関数をお持ちの場合は、それはC言語かPOSIXによって定義されていません。 –

+0

ローカル変数への参照を返していませんか? – Abhishek

+0

私はそれに問題は一度もなく、おそらくasprintfはメモリを割り当てます。 –

2

#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新しいサイズの配列を使用し、古いデータを代わりに入れてください。char配列の場合、最後の値は\0である必要があります。 calloc()はすべての値を\0に設定します。これはchar配列に優れています。

こちらがお役に立てば幸いです。

2

オリジナルポスターは、書くことを意味するものではありませんでした:

char* str = "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; 
    } 
-1

、これが最善の解決策でした私が見つかりました:C++での

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

私には未定義の動作のようです。私はあなたがフォーマット文字列( '"%s ... "、str、...')の引数の1つとしてターゲット引数 'str'を渡すことは許可されていないと思います。 – melpomene

-4

を、あなたは単にによってstringcharを追加することができます。

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

これはC++であり、Cではありません。 – melpomene

関連する問題