あなたは問題のセットアップを持っているかを見てから、あなたが入力の一部である文字、および周波数を保持する配列上の反復が混乱しているように見えます読み込まれた文字の
コードを読みやすくするために、コードにマジックナンバーを使用しないでください。 32
および126
。代わりに、表示しようとしている文字を使用してください。
(スペース)および~
(チルド)である。
for(j=32; j<126; j++){
あなたが使用することができ
を::
for(j = ' '; j < '~'; j++){
あまりにもそれが落とし穴だ持っていることたとえば、代わりに使用します。どうして?文字をループしたくない場合は、実際には各文字が入力に出現する頻度を保持する配列count
の要素をループします。言い換えれば、あなたの入力に各文字が出現する頻度を保持する最小の95
の整数を保持する配列が必要です。文字がどのようになるかを知っているので、32
〜126
の後ろに隠してはいけません。tools.h
に配列サイズの定数(ARSZ
など)を宣言してください。
#define ARSZ 95
は、その後、あなたの入力を読み取り、count
配列を充填した後、それはmostoften
またはleastoften
いずれかの番号を取得するには、一度count
配列を反復処理するだけです。さらに、count
の要素数の定数があるため、count
のサイズをmostoften
とleastoften
に渡す必要はありません。存在する要素の数はすでに知っています(95
)。
(配列のサイズが一定でない場合(のヌル終了文字列のようなセンチネルを持つ配列を渡さない場合)または数値コンパイル時に配列のサイズを渡す必要があります。
(また、Cは一般的に変数名にすべて小文字を使用しますが、通常は表示されませんMixedCaseまたはcamelCase Cの変数名はC++のままにしてください)
次に、コマンドライン引数の処理にgetopt
を使用する必要がありますが、問題の引数の2番目の文字を確認するのは簡単ですが、チェックするには少なくとも1つの引数があることを検証する必要があります。引数が空文字列ではありません。基本的には、チェックしたい:
if (argc > 1 && *argv[1]) /* check argc & not empty-string */
switch (argv[1][1]) {
case 'm':
mostoften (count);
break;
case 'M':
mostoften (count);
break;
case 'l':
leastoften (count);
break;
case 'L':
leastoften (count);
break;
default:
fprintf (stderr, "warning: unrecognized option, using 'mostoften'.\n");
mostoften (count);
}
else {
fprintf (stderr, "warning: no option given using 'mostoften'.\n");
mostoften (count);
}
ノートを:あなたは、任意の単一の場合のために2つの一定の条件を置くことができないあなたのswitch
(いくつかのコンパイラは非標準の拡張機能を提供)。また、default
の場合にはbreak
は必要ありません。フォールスルーはありません。
あなたが書くことができ、完全にそれを置くあなたのtools.h
類似した:
#include <stdio.h>
#include <limits.h>
#define ARSZ 95
int mostoften (int *a);
int leastoften (int *a);
あなたtools.c
として:
#include "tools.h"
int mostoften (int *a) {
int i, max = INT_MIN, cha = '0';
for (i = 0; i < ARSZ; i++)
if (a[i] > max) {
max = a[i];
cha = i + ' ';
}
printf ("char '%c' : %d times\n", cha, max);
return max;
}
int leastoften (int *a) {
int i, min = INT_MAX, cha = '0';
for (i = 0; i < ARSZ; i++)
if (a[i] < min) {
min = a[i];
cha = i + ' ';
}
printf ("char '%c' : %d times\n", cha, min);
return min;
}
あなたは知っているmax
またはmin
は、2種類の文字のために同じである場合最初の文字を選択し、leastoften
の場合は、常に0
の周波数の最初の文字を選択します。この問題を解決するには、入力に存在する文字を追跡し、その文字の頻度のみを考慮する2番目の配列(または2次元配列または構造体)を保持する必要があります。
最後に、あなたのmain.c
のようなものに書くことができますがあり、このタスクを達成するためにさまざまな方法がありますが、あなたの最初のコードを考えると、これはあなたの意図のように見えるものに保つ
#include "tools.h"
int main (int argc, char **argv) {
int c = 0, count[ARSZ] = {0};
while ((c = getchar()) != EOF)
if (' ' <= c && c <= '~')
count[c - ' ']++;
if (argc > 1 && *argv[1]) /* check argc & not empty-string */
switch (argv[1][1]) {
case 'm':
mostoften (count);
break;
case 'M':
mostoften (count);
break;
case 'l':
leastoften (count);
break;
case 'L':
leastoften (count);
break;
default:
fprintf (stderr, "warning: unrecognized option, using "
"'mostoften'.\n");
mostoften (count);
}
else {
fprintf (stderr, "warning: no option given using 'mostoften'.\n");
mostoften (count);
}
return 0;
}
を。あなたが何か質問がある場合はそれを見て、私に知らせてください。構造体を使用せずに入力内の文字を追跡する最も簡単な方法をご希望の場合は、count
をcount[ARSZ][2]
と単純に宣言し、追加要素を使用して文字が存在することを示します。 (配列に関数int a[][2]
またはint (*a)[2]
として渡すことができます)幸運。
ケース 'm':ケース 'M': 'を別の行に入れてください。 –
'switch(argc> 1 && argv [1] [1]){'は(argc> 1)switch(argv [1] [1]){' – BLUEPIXY
を編集してください。入力と期待される出力。 –