最初にコードに関するいくつかのコメント:
- 他の誰かがコメントで既に述べているように、 n文字列を保持するにはサイズn + 1のバッファーが必要です。これは、C では文字列の長さがどこにも格納されないためです。代わりに、文字列の終わりを示す特別な NUL バイトが文字列に追加されます。したがって、、 …、配列の長さは少なくとも 6 にする必要があります。
first
fourth
- 最悪のケースが発生し、ユーザーがそれぞれ 5 文字に相当する 4 つのバラバラな単語を入力した場合はどうなるでしょうか? 結合された文字列は 20 文字になります。したがって、
stack
配列は 21 文字 (終端 NUL バイトの場合は 1) に対応できる必要があります。( user3121023のコメントでも言及されています。)
- を使用して文字列を読み取るには、 ではなく
scanf
型の引数を渡します。 はすでに に減衰しているため、追加でそのアドレスを使用しないでください ( のように)。そのようなバグについて通知を受けるには、コンパイラの警告を有効にしてください (少なくとも を使用してください)。(この回答を入力しているときに、 Dere0405によっても言及されました。)char *
char (*)[6]
first
char *
&first
-Wall
- の使用
scanf
は安全ではありません。ユーザーが 5 文字を超える文字列を入力すると、配列の末尾を超えて読み取ることになります。フォーマット指定子を read に変更して、5 文字目以降の読み取りを停止%5s
するように指示することができます。scanf
ただし、これにより余分な文字が行末に残ります。より良いオプションは、入力行全体を使用fgets
または読み取ることです。getline
または、文字列をコマンドライン引数として渡すだけです (私の推奨ソリューション)。
実際の問題に移ります:
これは宿題に非常によく似ているため、完全な解決策は提供しませんが、いくつかのヒントのみを提供します。(残念ながら、他の誰かがすでに完全なコードを提供しているため、私の回答は無視される可能性があります。)
5 つの文字列すべてをループし、各文字が既にstack
. ある場合は続行し、そうでない場合は に追加しますstack
。文字列をループするには、次のイディオムを使用できます。
int i;
for (i = 0; first[i]; ++i)
printf("The character at position %d is '%c'\n", i, first[i]);
または、現在のインデックスを参照する必要がない場合は、次のイディオムがよりコンパクトになります。
char * pos;
for (pos = first; *pos; ++pos)
printf("The current character is '%c'\n", *pos);
first
C 文字列であるため、false と評価される NUL バイトで終了するという事実をどのように使用するかに注意してください。そうでなければ、反復をどこで止めればよいかわかりません。
文字列の文字をループする方法がわかったので、文字が既に追加されているかどうかを確認するにはどうすればよいでしょうか? 次の 2 つの解決策が考えられます。
ループしてstack
、各要素を問題の現在の文字と比較します。短い文字列ではこれが最適な方法かもしれませんが、長い文字列では効率が低下します。
文字ごとにカウンターを作成し、 に追加するたびにインクリメントしますstack
。char
s は単なる数字であるという事実を利用できます。char
したがって、最初はすべて 0 に設定された256 要素 (256 の異なる があります) を持つ配列を作成し、現在追加されている文字の位置をインクリメントすることができます。例えば:
int counters[256];
memset(counters, 0, sizeof(counters)); /* fill with 0s */
そして、コードの後半で:
if (counters[(unsigned char) (*pos)]++)
{
/* Character was already added. Do nothing. */
}
else
{
/* Character was not added yet. Add it to stack. */
}
はif (counters[(unsigned char) (*pos)]++)
少しトリッキーです。まず、*pos
ポインターを参照して現在の文字を生成し、配列は負のインデックスを持つことができないためpos
、現在の文字として解釈されます。unsigned char
次に、その位置がcounters
配列で検索され、if
ステートメントで評価されます。最後に、ポストインクリメント演算子を介して値がインクリメントされます (ただし、比較後のみ)。
stack
最後に NUL バイトで終了することを忘れないでください。