2010-12-02 12 views
3

ここの初心者はここにあります。 私がchar *の文字を置換しようとしていたが、私のプログラムがエラーchar *にcharを置き換える方法*

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    char *mystring ="love is alweys better yoe"; 
    int count = 1; 

    for (count ; count < 23; count++) 
    {  
    if ((mystring[count] == 0x65)) //&& ((mystring[count+1] > 0x41) && (mystring[count+1] < 0x7A))) 
    { 
     mystring[count] = 0x45; //here occur the freezing 
     printf ("%c\n", mystring[count]); 
     //break; 
    }; 
    }; 

    printf("%s\n",mystring); 
    return 0; 
} 

答えて

10

char *mystring ="love is alweys better yoe" 

が列MyStringが読み取り専用

をあなたが前にバッファに文字列をコピーする必要があります提供しますあなたはそれを変更することができます

char mystring[128]; 
strcpy(mystring , "love is alweys better yoe"); 
+0

aha。どうもありがとう。 – avar

9

スタック割り当て

char *mystring ="love is alweys better yoe"; 

これは読み取り専用メモリ内の文字列リテラルを作成し、あなたはその後、文字を変更するには、それに書き込むことはできません。

あなたはこの代わりのように、あなたの文字列を初期化する必要があります

char mystring[] ="love is alweys better yoe"; 

これはサイズ26バイトの文字配列に割り当てます - 文字あたり1バイト、ヌル文字\0で終了します。

バッファの末尾(つまり、\0文字を超えて)を超えて書き込もうとすると、プログラム内の他のデータに割り当てられたメモリに侵入している可能性があります。

ヒープ割り当て

前の例では、スタックにメモリを割り当て、および範囲の電流レベル(あなたがいる通常機能)の終了時にfree'dします。あなたはメモリが関数呼び出しの終わりを超えて持続する場合は、そのようなヒープ上にそれを割り当てる必要があります。

int bufferSize = 26; 
char* mystring = malloc(bufferSize); 
strncpy(mystring, "love is alweys better yoe", bufferSize); 

そして、あなたは、あなたがそれで行われたときに、このメモリをfreeすることを忘れないでくださいする必要があります。呼び出し元の関数からINGの

free(mystring); 

free場合、それはfreeにどのメモリ位置を知っているので、あなたは、呼び出し元にchar*のポインタを返す必要があります。このメモリがfreeでなければ、プログラムがメモリをリークします。

あなたはそれのためにメモリを割り当てた後の文字列をサイズし直す必要がある場合は、あなたがreallocを使用することができ、文字列のサイズ

を増やす:

char* mybiggerString = realloc(mystring, bufferSize + 10); 
strncpy(mystring, "I can fit more in this string now!", bufferSize); 
+0

@ sje397 - おっと、私もそれに気づいた。一定。 – LeopardSkinPillBoxHat

+0

素晴らしい情報、ありがとうございます。 – avar

+0

char mystring [] = "some string"は、文字列と\ 0文字を割り当てる前に、配列mystringの正しい長さを考えるようコンパイラーに指示します。 – buddhabrot

5

「CHARに*」は無意味です。ポインタの中にあるものは変更できません。ポインタには何も入っていないからです。物を含んでいないからです。それは物事を指します。それが「コンテナ」ではなく「ポインタ」と呼ばれる理由です。

char *mystring ="love is alweys better yoe";と記述すると、mystringの文字列リテラルを指します。これは、テキストを保持するための専用メモリです。 は変更されない可能性がある特別なメモリ領域です。 (テキストは.exeファイルに保存されていますが、ほとんどの実装では、OSは.exeファイルをメモリにロードし、ロードされた.exeの部分にポインタをポイントします。 - 基本的には、ウイルスを作成するのが難しくなります。)

解決方法:変更可能なメモリチャンクを使用してください。このように書く:char mystring[] = "love is alweys better yoe";。文字列リテラルはあなたのプログラムにはまだ残っていますが、これはプログラムが(変更可能なメモリ内に)バッファを作成し、リテラルをバッファにコピーするように指示します。このバッファーはリテラルとまったく同じ長さなので、は文字列にを追加しないことがあります - 既存の文字を変更するか、または切り捨てる(途中でヌルバイトを書き込むことによって)切り捨てます。

+0

情報ありがとうございます。 – avar

+0

私は、私が見たコードについて質問しました。それは引数として 'UChar * buffer'をとり、 'buffer [i] = somechar'を実行する関数です。これはどのように読み取り専用ではないのですか? (btw UCharはtypedef uint16_t UChar;) – avar

+1

読み取り専用は変数の型とは関係ありません。それは値の格納場所と関係があります。ポインタはデータを格納しません。それはデータを指しています。データは読み取り専用であるか、読み取り専用ではありません。配列を関数に渡すコードを書くと、Cは実際に配列の先頭にポインタを渡します。これは「ポインタの減衰」と呼ばれます。呼び出し元に "データを変更したいので、私に読み取り専用メモリーへのポインタを与えないでください"という警告を出すために、関数はそのパラメーター "buffer"という名前を付けました。 –

関連する問題