4

この関数を見つけましたが、その一部がわかりません。私は約3日分のCの経験があるので、我慢してください。この関数は、コマンドライン引数を解析する目的で使用されます。

  1. なぜ彼らはに再割り当て*argするの*cですか?

  2. なぜwhileループを実行しているのかわかりません。

  3. 次に、charポインターに対してwhileループを実行するのはなぜですか?charは実際には文字の配列であることを理解していますが、charに対してwhileループを実行するのは、配列の文字値に個別にアクセスするためだけであり、そのようなことはしません。

  4. どのように文字に対してインクリメントできますか?

  5. なぜ*cさえあるのですか?

  6. 文字列チェックを追加して、-stylesたとえばargがであるかどうかを確認します-。これにより、フラグを解析して、次のargである値を取得できますargv—これは正しく使用されていますか?

私が言ったように、私は約3日間のCの経験を持っているので、この機能とC全体をよりよく理解するのを助けるために、徹底的かつ系統的で、可能な限り役立つようにしてください。

void print_args(int argc,char *argv[])
{
     int i;
     if(argc > 1){
       for(i=1;i<argc;i++){
           char *arg = argv[i];
           char *c = arg;
           while(*c){
             if(strchr("-", *c)){
                 printf("arg %d: %s -> %s\n",i,arg,argv[i+1]);
             }  
             c++;
         }
       }
     }
 }
4

4 に答える 4

2

1)arg現在のchar配列の先頭を指すように割り当てられc、配列をトラバースするために使用されます。

2,3,5)whileループは、をc指すまで実行されます。(char)0これも偶然です\0。したがって、実際には、nullターミネータシンボルに到達するまで、char配列内のすべての文字を調べます。while (*c != '\0')暗黙的に依存するのではなく、より良い条件付きでした'\0' == 0

4)ポインタをインクリメントし、次のメモリセル、つまり次の配列セルを指すようにします。

6)追加はオプションを認識するためのテストとして機能しますが-styles、それが実際に有効なオプションであることを確認するには、それを比較する必要があります。

このコードサンプルは、より堅牢で明確にするために多くの修正を行うことができます。これが本またはCチュートリアルからのものである場合は、別のものを探すことをお勧めします。

于 2012-11-24T23:58:12.937 に答える
1

私は他に何も含まれていないプログラムprint_argsの機能に変わり、それを実行しました。mainこれはそれがすることです:

$ ./a.out a ab abc abcd
arg 1: a -> ab
arg 2: ab -> abc
arg 2: ab -> abc
arg 3: abc -> abcd
arg 3: abc -> abcd
arg 3: abc -> abcd
arg 4: abcd -> (null)
arg 4: abcd -> (null)
arg 4: abcd -> (null)
arg 4: abcd -> (null)

つまり、各コマンドライン引数の文字ごとに、そのコマンドライン引数全体、細い矢印、および次のコマンドライン引数を出力します。(私のCライブラリがうまくいかなかった場合、最後に到達するとクラッシュします。)コマンドライン引数全体printf("%s", (char *)NULL)を印刷すると、との両方が必要になりますが、その行は完全に読み取ることができます。carg

printf("arg %d: %s -> %s\n", i, argv[i], argv[i+1]);

その後、arg不要になります。

あなたの推測は、なぜこの関数がこの特定のことをするのかについて私のものと同じくらい良いです。私には、それを行うのは特に便利なことではないようです。

編集:あなたの目標が印刷することでargv[i]あり、ダッシュで始まり、 NULLではない場合argv[i+1](これは実際には文脈上意味があるかもしれません)、次のように書く必要があります:argv[i]argv[i+1]

void
print_args(int argc, const char *const *argv)
{
    int i;
    for (i = 0; i < argc; i++)
        if (argv[i][0] == '-' && argv[i+1])
            printf("arg %d: %s -> %s\n", i, argv[i], argv[i+1]);
}

ダッシュargv[i] が含まれている場合はいつでも印刷する場合は、

argv[i][0] == '-'

strchr(argv[i], '-')

ifステートメントで。

補遺:最新のUNIXコマンドラインプログラムが引数をどのように解釈するかを説明しているhttp://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.htmlを読むことを強くお勧めします。

于 2012-11-25T00:08:04.313 に答える
1

コードが行う個々のことのほとんどは、単独で意味をなす可能性がありwhileますが、の文字のループargは奇妙です。これは、「arg内のすべてのダッシュに対してargとnextargを出力する」のようなものです。しかし、私は誰もが本当にそれを望んでいるとは思えません。

于 2012-11-25T00:01:50.313 に答える
0

ポインタをインクリメントすると、そのポインタの次のアドレスに移動します。たとえば、アドレス0000にいて、次のアドレスが0004、0008などであるとします。そのアドレスの値は、たとえば、文字列内の文字である可能性があります。したがって、文字列が「hello」の場合、* cは「h」になり、最初の*c++は「e」になります。

whileループは、無限ループに陥りやすいため、通常、最も効率的な方法ではありません。文字列内のすべての文字が考慮されていることを確認するためです。

なぜ彼らがargを*cに割り当てるのか完全にはわかりません。

于 2012-11-24T23:57:03.357 に答える