• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:配列をstrtokする方法)

配列をstrtokする方法

このQ&Aのポイント
  • 配列をstrtokを使用して分割する方法を教えてください。
  • また、作成した配列を元に構造体のメンバーが存在するかどうかを検索する方法を教えてください。
  • よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

C言語での文字列の使い方について勉強した方が良いかもしれません。 スクリプト言語と違って、C言語で文字列というのはchar型の配列に過ぎません。そして、プログラムを書く場合は常にそれを意識せざるを得ません。"abc"という文字列は{'a', 'b', 'c', '\0'}というchar型の配列でしか作れませんし、文字列処理関数を使ったところでそのことを忘れることはできません。この意味で文字と文字列というのは明確に区別されています。 また、C言語では変数の型が大事な意味を持ちますので、変数の型を省略することはできません。 以上のことを踏まえ、個人的には「これで作ってコンパイルはエラーになりませんでした。」というのは何か誤解しているか嘘だと思っています。ちなみに、自分が質問者がお書きになったプログラムをgccでコンパイルしたところ、エラーと警告が大量に出て、大幅に手直ししないとコンパイルでエラーや警告が出ない状態にはできませんでした。 strtokは関数自体に状態を持つ関数で、FreeBSDのmanualではobsoleted by strsepと言われているので、自分は使わないですね。FreeBSDのstrsepのマニュアルにはトークンに分ける方法がばっちり載っているのでそれでやってみたのを下記に載せます。 > 上記ret_keyで作成したキーを元に、 > 構造体のメンバーがあるか検索することは可能でしょうか。 > ご存知だったらご教授願いたいです。 何をしたいのかあまりよくわからないのですが、 test1|on+test2|offとあったときに、 test1で検索するとonが返り、test2で検索するとoffが返るという例ならちょっと作ってみたので下記で示します。 以下、人が書いたプログラムを読むのも良い勉強だと思うので質問者がやりたいであろうことを予測してコードを書いてみました。parse_configで"test1|on+test2|off"を解釈し、config構造体を動的に割り当てた上でそれに入れ、list_configで一覧表示、find_configで特定の値の取得、free_configでconfig構造体の解放をしています。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_KEYS 200 #define NUMELMS(X) (sizeof(X)/sizeof(X[0])) struct config { char *tokenized_config; char *key[MAX_KEYS]; char *val[MAX_KEYS]; size_t num_entries; }; /* * Parses config and returns config structure if succeeded. Otherwise, NULL. * Caution: you SHOULD free the returned config structure instance by yourself * using free_config function. */ struct config * parse_config(char *input) { char *tmp_ary[MAX_KEYS]; struct config *config; char **ap, *to_tokenize; char *p; int i; config = malloc(sizeof(config[0])); if (config == NULL) { return NULL; } to_tokenize = config->tokenized_config = strdup(input); if (to_tokenize == NULL) { free(config); return NULL; } // 一回目 // http://www.unix.com/man-page/FreeBSD/3/strsep/ for (ap = tmp_ary; (*ap = strsep(&to_tokenize, "+")) != NULL;) if (**ap != '\0') if (++ap >= &tmp_ary[NUMELMS(tmp_ary)]) { fprintf(stderr, "Warning: MAX_KEYS is smaller than actual config."); break; } config->num_entries = ap - tmp_ary; // 二回目 for (i = 0; i < config->num_entries; i++) { config->key[i] = tmp_ary[i]; p = strchr(tmp_ary[i], '|'); if (p != NULL) { *p = '\0'; config->val[i] = p + 1; } else { config->val[i] = "\0"; } } return config; } /* * Returns value if in the config. Otherwise, NULL. */ char * find_config(struct config *c, char *key) { int i; for (i = 0; i < c->num_entries; i++) { if (strcmp(c->key[i], key) == 0) return c->val[i]; } return NULL; } /* * Lists configs. */ void list_config(struct config *c) { int i; for (i = 0; i < c->num_entries; i++) { printf("%s=%s\n", c->key[i], c->val[i]); } } /* * Free an instance of config structure. */ void free_config(struct config *c) { free(c->tokenized_config); free(c); } int main(void) { struct config *config = parse_config("test1|on+test2|off"); if (config == NULL) { fprintf(stderr, "failed to allocate config."); exit(EXIT_FAILURE); } list_config(config); printf("%s\n", find_config(config, "test1")); printf("%s\n", find_config(config, "test2")); free_config(config); return 0; } ISO C90でコンパイルできる程度の関数しか使っていないと思うので、おそらくどのコンパイラーでもコンパイルできると思います。 あとはいろいろといじってみて動きを理解してくださいな。

prr4e
質問者

お礼

返事がおそくなって申し訳ありまん。 こちら色々やったり聞いたりして無事解決できました。 有難う御座いました。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

> p = strtok(test_ary, "+"); > tmp_ary[0] = *p; これは 「tmp_ary[0] に 文字列 p の先頭の1文字を代入」 ですよ。他の言語では こんな感じで文字列のコピーを作ったりできますけど、Cではそんな風に扱える「文字列」はありません。 あくまで「charの配列」であって、配列でできないことは、「文字列」でもできません。 文字列、配列、ポインタのあたりをよく復習してください

すると、全ての回答が全文表示されます。
  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.1

変数の型が省略されてたりするのはなぜ? >これで作ってコンパイルはエラーになりませんでした。 警告はありそうな気がしますけど無視していませんか? >又別件で、 >上記ret_keyで作成したキーを元に、 >構造体のメンバーがあるか検索することは可能でしょうか。 何をやりたいのかがまったくわかりません。

すると、全ての回答が全文表示されます。