- 締切済み
C言語で文字列からパラメタをsscanfで取得する上手な方法はありませんか
C言語で、 char buf[100]="\"日 本 語 12 3\"," ",,\"aa\",,2,\"\",\"aaa\""; から para1=日 本 語 12 3 para2=<空白> para3=なし para4="aa" para5=(なし) para6=2 para7=(なし) para8=aaa を取得するようなうまい方法はありませんか。 条件 1)項目はカンマでくぎってあるとする 2)項目に値がない場合として、""あるいは何もない場合がある。 3)""の中の値には日本語や英数字が入っている。 OSはSolaris(UNIX)です。 よろしくお願いいたします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- leaz024
- ベストアンサー率75% (398/526)
bufの中身は恐らく変わるんですよね? だとすればsscanfでの値取得は不可能だと思います。 標準関数のstrtokではヌル文字列が取れないので、ヌル文字列も取得できる拡張strtok関数を作ればいいのではないでしょうか。 (ただし分離記号は1つとし、切り出したトークンを囲むダブルクォートは除去します。) #include <stdio.h> #include <string.h> char *ex_strtok(char *ptr, int delim) { static char *sptr = NULL; char *tok, *p; if (ptr != NULL) { sptr = ptr; } /* 初回は文字列をセット */ else if (sptr == NULL) { return NULL; } /* 取れない場合NULLを返す */ tok = sptr; if (p = strchr(sptr, delim)) { /* delimを探す */ sptr = p + 1; /* sptrを次の先頭へ */ } else { p = sptr + strlen(sptr); /* pを文字列終端へ */ sptr = NULL; /* 次回はNULLを返す */ } if (*tok == '\"') { /* 先頭が"なら */ tok++; /* 頭の"はスキップ */ *(p-1) = '\0'; /* 尾の"は\0に変換 */ } *p = '\0'; /* 分離記号を\0に変換 */ return tok; /* トークンを返す */ } int main(void) { char buf[100]="\"日 本 語 12 3\",\" \",,\"aa\",,2,\"\",\"aaa\""; char *para; para = ex_strtok(buf, ','); /* 最初はbufをセット */ do { printf("<%s>\n", para); } while (para = ex_strtok(NULL, ',')); /* 次回以降はNULLでコール */ return 0; } 実行結果 <日 本 語 12 3> < > <> <aa> <> <2> <> <aaa> これならbufの中に、いくつパラメータがあってもOKでしょ? ただしex_strtokは、strtok同様に、第1引数の文字列を変更してしまいますので、元の値が必要な場合は、作業領域にコピーしてから実行してください。
- a-kuma
- ベストアンサー率50% (1122/2211)
ギブアップ。 専用の関数を作らないと駄目でしょう。ダブルクォーテーションを 削除していませんが、こんな感じか。 #include <stdio.h> #include <stdarg.h> void split_by( char *str, char sep, ... ) { va_list ap; char* to; char* p; va_start(ap, sep); to = va_arg(ap, char*); p = str; while (*p) { if (*p == sep) { *to = '\0'; to = va_arg(ap, char*); } else { *to++ = *p; } ++p; } *to = '\0'; va_end(ap); } int main(void) { char buf[100]="\"日 本 語 12 3\",\" \",,\"aa\",,2,\"\",\"aaa\""; char para1[30], para2[30], para3[30], para4[30], para5[30], para6[30], para7[30], para8[30], para9[30]; split_by(buf, ',', para1, para2, para3, para4, para5, para6, para7, para8, para9); printf("para1=<%s>\n", para1); printf("para2=<%s>\n", para2); printf("para3=<%s>\n", para3); printf("para4=<%s>\n", para4); printf("para5=<%s>\n", para5); printf("para6=<%s>\n", para6); printf("para7=<%s>\n", para7); printf("para8=<%s>\n", para8); printf("para9=<%s>\n", para9); return 0; } 実行結果。 para1=<"日 本 語 12 3"> para2=<" "> para3=<> para4=<"aa"> para5=<> para6=<2> para7=<""> para8=<"aaa"> para9=<>