• 締切済み

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)です。 よろしくお願いいたします。

みんなの回答

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.2

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)
回答No.1

ギブアップ。 専用の関数を作らないと駄目でしょう。ダブルクォーテーションを 削除していませんが、こんな感じか。 #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=<>

関連するQ&A