0

strtok()やstring.hからの何かを使用せずに、スペースで文字列を手動で解析しようとしています。これは正しいアプローチのように見えますか?これを試してみると、文字列の終わりを過ぎてスキップし続けます。

  char cmd[1024];
  int ret = read(STDIN, cmd, 1023);
  cmd[ret-1] = '\0';

     char * args[128];
     int length = 0;
     char * startptr = cmd;
     char * endptr = cmd;

     while(1){
        if(*startptr == '\n' || *startptr == '\0'){
           break;
        }
        if(*startptr == ' '){
           startptr ++;
           endptr ++;
           continue;
        }
        // startptr is placed
        if(*endptr != '\0' || *endptr != '\n' || *endptr != ' '){
           endptr ++;
           continue;
        }
        // both pointers placed
        char * i = startptr;
        for(i = startptr; i != endptr; i++){
           args[length][i-startptr] = *i;
        }
        length ++;
        startptr = endptr;
        if(*endptr == '\0' || *endptr == '\n'){
           break;
        }

     }
4

3 に答える 3

2

いいえ、正しくありません。論理式は'および'ではなく'または'である必要があります。
制限をチェックするのは良いことですが、「ARG_MAX_LENを2に変更」のように、すべての単語の最初の文字を取得するなど、興味深い効果が得られる場合があります。おそらくこのコードは機能します。

 char cmd[1024];
 int ret = readf(cmd, 1, 1023, stdin);

 char args[128][ARG_MAX_LEN]; //two dimensional array 
 int length = 0;
 char * startptr = cmd;
 char * endptr = cmd;
 char *ap, *aep;
 if(ret > 0)
   cmd[ret-1] = '\0';
 else
   cmd[0] = '\0';
 while(*startptr != '\n' && *startptr != '\0')
 {
    if(*startptr == ' '){
       endptr = ++startptr ;
       continue;
    }
    // startptr is placed
    if(*endptr != '\0' && *endptr != '\n' && *endptr != ' '){
       endptr ++;
       continue;
    }
    // both pointers placed
    ap = &args[length][0];
    aep = ap + ARG_MAX_LEN - 1;
    while(startptr != endptr && ap != &args[length+1])
      *ap++ = *startptr++;
    if(length >= 128)
       break;
    length ++;
    startptr = endptr;
 }

コマンドライン引数を取得する場合は、文字のエスケープも探す必要があります。

于 2012-04-15T23:06:50.197 に答える
1
if(*endptr != '\0' || *endptr != '\n' || *endptr != ' '){

ここで&&を使用する必要があります:

if(*endptr != '\0' && *endptr != '\n' && *endptr != ' '){

また、args [length]を割り当てていないため、そこに書き込もうとすると、おそらくセグメンテーション違反が発生します。最初にスペースを割り当てるmallocか、2D配列を使用する必要があります。

また、ここで1つのエラーが発生します。

cmd[ret-1] = '\0';

-1を指定すると、バッファ内の最後の文字が上書きされます。さらに悪いことに、ファイルが空の場合は、に書き込まれcmd[-1]ます。

于 2012-04-15T21:35:06.977 に答える
0

あなたのアプローチは正しくありませんが、どちらも(私の意見では)あなたが受け入れた答えではありません(申し訳ありませんがuser1333967)。

すでに指摘されている論理エラーとは別に、ネストされたループがあります。それらはほとんどの場合、よく考えられていないコードを示しているため、避ける必要があります(賢明な場合もありますが、これは1つではありません)。

関数は、特に文字列処理の友だちです。標準ライブラリのstrtok、strcpy、strchrなどを使用したくない場合は(奇妙な理由で-宿題かもしれませんが)、自分で作成してください。それらは非常に書きやすく、コードを単純化し、読みやすくします。関数呼び出しのオーバーヘッドについて不平を言う人は無視してください。99%の確率で重要ではありません。

于 2012-04-16T03:26:26.360 に答える