2

たとえば、文字列がある場合: (つまり、4 番目のフィールド)だけを取得するにはHi:my:name:is:lacrosse1991:どうすればよいでしょうか? これは、bash でカットを使用する方法に似ています。これがそのようなことをするのに間違った機能である場合は、お知らせください。どんな助けでも大歓迎です、ありがとう! (私は最近 C の独学を始めたばかりです。これらが私が尋ねている明らかな質問である場合は、事前にお詫びします)strtokiscut -d ":" -f 4

これは私が使用するカットコマンドの例です

x=$(echo "$death" | cut -d ':' -f 4)
y=$(echo "$death" | cut -d ':' -f 5)
z=$(echo "$death" | cut -d ':' -f 6)
4

3 に答える 3

6

それが 4 番目のフィールドであることがわかっている場合は、strtok() を 4 回呼び出すだけです。文字列全体をスキャンせずに 4 番目のフィールドにジャンプする方法はありません (これが strtok の機能です)。

于 2012-05-09T03:37:14.483 に答える
1

th フィールドを抽出する 1 つの方法N(呼び出し後に文字列を元の状態に保ちながら) は、次のgetFld関数を使用することです。まず、必要なヘッダー:

#include <stdio.h>
#include <string.h>
#include <malloc.h>

これで、関数自体が十分に文書化されていることを願っています。

char *getFld (char *srchStr, char delim, int numFld) {
    char *copyStr, *retStr, *tmpStrPtr, delims[2];

    // Make a copy so as to not damage original.

    if ((copyStr = strdup (srchStr)) == NULL) return NULL;

    // Create delimiter string from character.

    delims[0] = delim; delims[1] = '\0';
    retStr = NULL;

    // Start loop, extracting fields.

    tmpStrPtr = strtok (copyStr, delims);
    while (tmpStrPtr != NULL) {
        // If this is the field we want, make a copy.

        if (numFld == 0) retStr = strdup (tmpStrPtr);

        // Get next field.

        tmpStrPtr = strtok (NULL, delims);
        numFld--;
    }

    // Clean up, return field copy (must be freed eventually) or NULL.

    free (copyStr);
    return retStr;
}

最後に、そのためのテスト プログラム:

int main (void) {
    int i = 0;
    char str[] = "Hi:my:name:is:lacrosse1991";
    char *fld;
    while ((fld = getFld (str, ':', i)) != NULL) {
        printf ("Field %d is '%s'\n", i, fld);
        free (fld);
        i++;
    }
    return 0;
}

これをコンパイルして実行すると、次のようになります。

Field 0 is 'Hi'
Field 1 is 'my'
Field 2 is 'name'
Field 3 is 'is'
Field 4 is 'lacrosse1991'

これは標準 Cではないことに注意してstrdupください。実装にない場合は、これを使用できます。strdup現在のケースは範囲外のフィールドと区別できないため、失敗時の動作を変更することもできます。

ただし、このコードは、最初のベースラインとしては問題ありません。

于 2012-05-09T04:10:50.580 に答える
1

私はstrtokこの目的のために(そして他のほとんどの場合も)避けたいと思います。sscanf状況下では、scanset変換で使用するだけだと思います:

char field_four[128];   
sscanf(input_string, "%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_four);

これでは、%*[^:]:3回繰り返すことから始めます。これらはそれぞれ、コロンを除く任意の文字を含む文字列を読み取り、次にコロンを読み取ります。入力から読み取る必要がある*手段ですが、無視されます (何にも割り当てられません)。次に、4 番目のフィールドについては、 を含めないことを除いて同じです。*そのため、この場合は にフィールド割り当てられfield_fourます (明らかに、より意味のある名前を使用する必要があります)。

4 番目のフィールドには、最大長の仕様も追加しました。文字列を終了するsscanfa は常に含まれますが、カウントには含まれないため、バッファーのサイズより 1 小さいサイズを指定する必要があります。\0

于 2012-05-09T04:21:36.053 に答える