プロが教える店舗&オフィスのセキュリティ対策術

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

A 回答 (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引数の文字列を変更してしまいますので、元の値が必要な場合は、作業領域にコピーしてから実行してください。
    • good
    • 0

ギブアップ。



専用の関数を作らないと駄目でしょう。ダブルクォーテーションを
削除していませんが、こんな感じか。


#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=<>
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!