2012-04-03 24 views
-1

可能性の重複:私はC.内の別の文字に文字列の文字を変更しようとしているので、
Problem with processing individual strings stored in an array of pointers to multiple strings in CCプログラミング - 文字列配列要素の変更文字

[OK]をつまり、各文字列は1D配列の要素なので、文字列自体が文字配列なので、本質的にすべて一緒に2次元配列になります。とにかく私はこれを行うコードを作成する問題があります。これも可能ですか?どんな助けもありがとうございます。ここで

はコードです:

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

int main() 
{ 
int i, size; 
char **a; 

a=(char**)malloc(sizeof(char*)); 

printf("Enter the size of the array:"); 
scanf("%d", &size); 

for(i=0;i<size;i++){ 
a[i]=(char*)malloc(sizeof(char)*8); 
} 

a[3]="Read"; 


while(*(a[3])!='\0'){ 
if(*(a[3]) == 'e'){ 
    *(a[3]) = 'r'; 
} 
} 

printf("%s\n", a[3]); 

system("pause"); 
return 0; 

} 
+0

正確な問題は何ですか?あなたは言わなかった。間違いはありますか? –

答えて

0

あなたはaのための十分なスペースを割り当てることができませんでした。代わりに

a=(char**)malloc(sizeof(char*)); 

のあなたは

a=(char**)malloc(sizeof(char*)*size); 

と明らかにこれを必要とsizeが読み込まれた後であることを移動しなければなりません。

あなた一度ソートそれはむしろ平凡な問題アウトは根本的な問題はここにある:

a[3]="Read"; 

これを変更することはできませんリテラルでポインタa[3]ポイントになります。代わりに、そのリテラルの内容をa[3]にコピーする必要があります。このように:

strcpy(a[3], "Read"); 

あなたはa[3]=...だけのポインタa[3]を割り当てへa[3]ポイントの文字列を変更しないことを理解しなければなりません。 sizeその後a[3]以来4未満の場合さて、あなたのコードは明らかにエラーになります

は範囲外になりますが、私はあなたがこれをデバッグしながら、a[3]はただ一時的であると思います。

あなたのwhileループはすべて間違っています。あなたはこのような何かをしたいあなたのコメントから判断:

char *p = a[3]; 
while (*p != '\0') 
{ 
    if (*p == 'e') 
     *p = 'r'; 
    p++; 
} 

Cでmallocの戻り値をキャストするので、キャストを削除する必要はありません。 sizeof(char)は常に1に等しいので、削除することもできます。

+0

それでは、配列とその要素に十分なメモリスペースを割り当てなかったのですが、別の問題があります。私は、a [3]に格納された文字列の文字をどのように置き換えるのか考えていないので、うまく動作しないwhileループを使ってみました。 – user1311135

+0

逆に、リテラルを変更することはできませんが、実際にはポインタを使用することができます。これは、読み取り専用メモリに入るようなものではありません。 –

+0

私たちにとってはうまくいかないです。それがあなたが提供するすべての情報であれば、どうすれば助けますか?それは、私はあなたの文字列の割り当てが間違っていたと私の答えで指摘した。代わりにstrcpyを使用してください。 –

0

この:

a=(char**)malloc(sizeof(char*)); 

は、1つの文字列のためのスペースを割り当てます。 a、例えば、a[3]の要素を逆参照することができます、この時点で

char **a = NULL; 
size_t number_of_strings = 8; /* for argument's sake */ 

a = malloc(number_of_strings * sizeof(char*)); 
if (!a) 
    return NOT_ENOUGH_MEMORY_ERROR; 

:あなたはおそらくつもりはのようなものです。あなたはまだあまりにもそれらの人のためのスペースを割り当てることになるでしょう。それと

char *staticStr = "Read"; 
a[3] = malloc(strlen(staticStr) + 1); 
strncpy (a[3], staticStr, strlen(staticStr) + 1); 

スタートし、メモリを割り当てるしている方法を再考すると、あなたの他のバグを修正するのに役立ちますかどうかを確認します。

いくつかの注意:

  • あなたは常に1
  • である、あなたがメモリを割り当てるためsizeof(char)を使用する必要はありません
  • C
  • mallocの結果をキャストする必要がある必要はありません。私はanoth参照して、メモリリークを
0

を防止するために、各a[i]およびa自体の対応free()を使用することえー問題、あなたがのためにメモリを割り当てるとき:

a = (char **) malloc(sizeof(char *)); 

あなただけの1の位置にメモリを割り当てているが、あなたはsize位置を使用しています。あなたのコードは:

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

int main() 
{ 
int i, size; 
char **a; 
char *ptr; 



printf("Enter the size of the array:"); 
scanf("%d", &size); 

a=(char**)malloc(size * sizeof(char*)); 

for(i=0;i<size;i++){ 
a[i]=(char*)malloc(sizeof(char)*8); 
} 

strcpy(a[3], "Read"); 

ptr=a[3]; 
while(*ptr!='\0'){ 
if(*ptr == 'e'){ 
    *ptr = 'r'; 
} 
ptr++; 
} 

printf("%s\n", a[3]); 

system("pause"); 
return 0; 

} 

となります。もちろん、割り当てられたメモリを解放する必要があります。

'e'を 'r'に変更しようとすると、いつも同じcharを指しています。配列をスローするには、新しいポインタが必要です。

1
a=(char**)malloc(sizeof(char*)); 

printf("Enter the size of the array:"); 
scanf("%d", &size); 

for(i=0;i<size;i++){ 
a[i]=(char*)malloc(sizeof(char)*8); 
} 

nope。 1 char*を割り当てました。次に、それはsize要素のように扱います。 size * sizeof(char*)バイトを割り当てる必要があります。 (この乗算もオーバーフローする可能性があります。)

a[3]="Read"; 

悪い回。文字列リテラルの場所が"Read"の場合は、a[3](以前は8文字の割り当てを指していました)を上書きしています。これにより、以前の割り当てがリークされ、変更不可能な文字列がa[3]に格納されます。あなたはstrncpyなどを見てください。このため。

0

あなたのwhileループは何もしません。

while(*(a[3])!='\0'){ 
if(*(a[3]) == 'e'){ 
    *(a[3]) = 'r'; 
} 
} 

ポインタを前進させず、最初の位置に保持します。

より適切っぽいな方法は、一時的なポインタを作成することや、文字列を歩くためにそれを使用することになり

char *temp = a[3]; 
while (*temp != '\0') { 
    if (*temp == 'e') *temp = 'r'; 
    temp++; 
} 
+0

私は他の人がそれをうまくやっていると思った。もちろん、リテラルを変更することができるので問題はありません。あなたはデバッグモードにすることはできませんが、そうすることはできません。 –

+0

@DavidHeffernan "char * a; a =" Hello! "; char * b = a; b [2] = 'b';"デバッグモードでエラーが発生し、正常に実行され、リリース時にも変更されました。証明はコンパイル中です。 –

+0

@DavidHeffernanと私は別のStackOverflowのコメントを引用しています。 "もともと、C89(C90)標準は、標準よりも前に書かれたコードが多すぎてリテラルの改変を禁止していませんでした。 GCC 3.xが持っていた-fwritable-stringsオプションはありませんが、GCC 3.xは少なくとも文字列の変更を警告します。人々は怠惰なルートをとらえています。 "後方互換性のための基準はそれを可能にします –