1

ファイルを読み取るためのファイル名として使用できるように、文字列にサブオプションを入れたいと思います。

char *nvalue = NULL;
char *dvalue = NULL;
char *input = NULL;
char inputfilename[] = "\"";
int ar;

int main(int argc, char *argv[])
{
   while ((ar = getopt(argc, argv, "hn:d:i:")) != -1)
      switch (ar)
      {
         case 'h':
            printf("something");
            break; /* added */
         case 'n':
            nvalue = optarg;
            if (isdigit(nvalue))
               stop = atoi(nvalue);
            else
               printf("something\n");
            break; /* added */
         case 'd':
            dvalue = optarg;
            if (!strcmp(dvalue, "FCFS")   || !strcmp(dvalue, "SSTF") ||
                !strcmp(dvalue, "C-SCAN") || !strcmp(dvalue, "LOOK"))
               ;
            else
               printf("Invalid type of disk scheduling policy entered.\n");
            break; /* added */
         case 'i':
            input = optarg;
            strcpy(inputfilename, optarg);
            printf("Filename :%s\n", inputfilename);
            break;
      }
   /* ... */
}

したがって、コマンドラインで次のように入力すると、次のようになります。

./foobar -i hello

次に、次のファイルを読み取ることができるはずです。

FILE *file = fopen(inputfilename, "r" );

助言がありますか?答え?ありがとう!

4

1 に答える 1

2

コードには多くの問題があります。私はヘッダーファイルがないことを無視しています(コードが正しいものを使用していると仮定して、すべての関数が使用前にスコープ内にプロトタイプを持っていると仮定します)。私もあなたのコードを冷酷に再フォーマットしていますが、それ以上のコメントはありません。

char *nvalue = NULL;
char *dvalue = NULL;
char *input = NULL;
char inputfilename[] = "\"";

これにより、2バイトの配列がとして割り当てられましたinputfilename。あなたがそれを使うとき、私は何が起こるかを考えるのが嫌いです。

int ar;

この変数がメイン関数に対してローカルである必要がある理由はすべてあり、グローバル変数である理由はありません。それらを宣言するヘッダーがない限り、他の変数もそうである必要があります-ローカルとしてそれらを渡す便利な方法なしでstatic外部からそれらの値にアクセスする必要があると仮定します。main()可能な限りグローバル変数を避けてください。

int main(int argc, char *argv[])
{
    while ((ar = getopt(argc, argv, "hn:d:i:")) != -1)
    {
        switch (ar)
        {
        case 'h':
            printf("something");

おっと; いいえbreak、コードはコードにドロップスルーしcase 'n':ます。Cはパスカルではありません。

        case 'n':
            nvalue = optarg;
            if (isdigit(nvalue))
                stop = atoi(nvalue);

の宣言を表示していませんstop。文字列が本当に必要でない限りnvalue、グローバル変数を避けて、なしで実行できます。これは常に望ましいことです。

            else
                printf("something\n");

別の行方不明break; 二度と指摘するつもりはありません。

        case 'd':
            dvalue = optarg;
            if (strcmp(dvalue, "FCFS")   == 0 ||
                strcmp(dvalue, "SSTF")   == 0 ||
                strcmp(dvalue, "C-SCAN") == 0 ||
                strcmp(dvalue, "LOOK"    == 0)
            {

のようなコメントをお勧めし/* Nothing - dvalue is OK */ます。または、ド・モルガンの定理を使用して条件を反転します。

            if (strcmp(dvalue, "FCFS")   != 0 &&
                strcmp(dvalue, "SSTF")   != 0 &&
                strcmp(dvalue, "C-SCAN") != 0 &&
                strcmp(dvalue, "LOOK"    != 0)

そのテストを、コードの配列の各要素に対して値をテストする関数にカプセル化することもできます。

            }
            else
                printf("Invalid type of disk scheduling policy entered.\n");

許容値のリストを提供するのは礼儀正しいでしょう。これは、リストを生成するために使用できる有効な値の配列を持つもう1つの理由になります。多くの場合、エラーメッセージは。ではなくstderr(を使用して)に報告する必要があります。fprintf()stdout

        case 'i':
            input = optarg;

この割り当てで十分です。

            strcpy(inputfilename, optarg);

inputfilenameユーザーが1文字のファイル名を入力しない限り、配列がオーバーフローしただけです。名前を変更する場合(たとえば、名前の拡張子を追加または変更する場合)を除いて、引数のコピーを作成する必要はありませんでした。

             //strcat(inputfilename,"\"");   
             printf("Filename :%s\n", inputfilename);
        }

default条項を含めませんでした。ユーザー提供のオプションが認識されない場合にar値が割り当てられるため、これは通常、簡単な使用法メッセージを提供して終了するための手がかりになります。?

于 2011-12-08T05:19:08.123 に答える