※「セキュリティ保護のため...」というメッセージが出る方・日本語が入力できない方へ
↑ 文字列分解結合


int InCha(const char* str, int cnt, char a);
int LineStrMix(char* str);
int LineStrSep(char* str, const char* lfcode);
char* my_strtok(char* str, const char* del);
char* my_strtok1(char* str, const char* del);
long my_strtok1L(char* str, const char* del);
long my_strtokL(char* str, const char* del);
double my_strtokD(char* str, const char* del);
char* my_buftok(char* str, int len);
long my_buftokL(char* str, int len);
試作品

#ifdef UTL_MAIN
char* my_strtok_ptr;
char  my_strtok_del;
int   swDebug = 1;
#else
extern char* my_strtok_ptr;
extern char  my_strtok_del;
extern int swDebug;
#endif

■文字が指定グループに入っているかどうかをチェックするルーチン。
 この手の処理は通常strstrでチェックするのだが、このルーチンは
 my_strtok用の特別仕様であり、それ以外の用途はあまりないかも。
/********************************************************************
 * 文字の位置 (0-origin, not found = -1)
 *******************************************************************/
int InCha(const char* str, int cnt, char a)
{
    int   k;

    k = 0;
    while(cnt--)
       {
        if (str[k]==a)
            return(k);
        k++;
       }
    return(-1);
}
■strtokを少し変形したものである。
  (1)strtokは最後まで文字列を読んでしまうと、その次の呼び出しで
     エラーが起きてしまう。これを避ける。
  (2)strtokが内部的に使用している変数をグローバルに置いて、strtok
     をネストして使うことを可能にした。
 (3)my_strtokL などは結果を数字で取り出すものである。使用している
    PickSuzi系についてはこちらを参照。

/********************************************************************
 * 文字列分解(strtok準拠,スコシチガウ)
 *******************************************************************/
char* my_strtok(char* str, const char* del)
{
    int   k;
    char* q;

    if (!str)
        str = my_strtok_ptr;

    while(InCha(del,strlen(del),*str)>=0)
        str++;
    if (*str==0)
       {
        my_strtok_del = 0;
        my_strtok_ptr = str;
        return(0);
       }
    for (q=str; *q; q++)
       {
        k = InCha(del, strlen(del), *q);
        if (k>=0)
            {
             my_strtok_del = del[k];
             my_strtok_ptr = q+1;
             *q = 0;
             return(str);
            }
       }
    my_strtok_del = 0;
    my_strtok_ptr = q;
    return(str);
}
long my_strtokL(char* str, const char* del)
{
    char* p;

    p = my_strtok(str, del);
    return( PickSuziS(p) );
}
double my_strtokD(char* str, const char* del)
{
    char* p;

    p = my_strtok(str, del);
    return( PickSuziSD(p) );
}
■strtokのバリエーションで区切り文字を1個ずつ使用するもの。
 例えば空白が2個続いている時、それを1個の空白とはみなさない。

/********************************************************************
 * 文字列分解(strtok準拠,スコシチガウ) 連続区切り文字を1個ずつ使う
 *******************************************************************/
char* my_strtok1(char* str, const char* del)
{
    int   k;
    char* q;

    if (!str)
        str = my_strtok_ptr;

    if (*str==0)
       {
        my_strtok_del = 0;
        my_strtok_ptr = str;
        return(0);
       }
    for (q=str; *q; q++)
       {
        k = InCha(del, strlen(del), *q);
        if (k>=0)
            {
             my_strtok_del = del[k];
             my_strtok_ptr = q+1;
             *q = 0;
             return(str);
            }
       }
    my_strtok_del = 0;
    my_strtok_ptr = q;
    return(str);
}
long my_strtok1L(char* str, const char* del)
{
	return PickSuziS(my_strtok1(str,del));
}

■buftok
  似たような文脈で使用するルーチンだが処理内容はまるっきり違う。
  これは固定長のレコードで使用するもので、指定桁のデータを取り
  出すものである。このルーチンはstrtok同様区切り文字部分を破壊
  するので注意。破壊が困る場合はMidStr系を使用のこと。

char* my_buftok(char* str, int len)
{
    if (!str)
        str = my_strtok_ptr;

	str[len]=0;
	my_strtok_ptr = str+(len+1);
	return str;
	
}
long my_buftokL(char* str, int len)
{
	return PickSuziS(my_buftok(str,len));
}
■複数行からなるデータを1個の文字列にまとめたり分解したりするもの
/********************************************************************
  改行を含む文字列をまとめる  (return=行数)
 *******************************************************************/
int LineStrMix(char* str)
{
	int i,j,k,m,r,len,c1,lcnt;
	char* buf;

	len = strlen(str);
	buf = (char*)malloc(len*2+1);
	for (i=j=k=m=r=lcnt=0; i<len; i++)
	{
		c1 = str[i]; if (c1<0) c1+=256;
		if (c1==13)		//CR
		{
			j=k;
			buf[j++]='\\';
			buf[j++]='n';
			if (str[i+1]==10)
				i++;
			k=j;
			lcnt++;
			m=0;
			continue;
		}
		if (c1==10)		//LF
		{
			j=k;
			buf[j++]='\\';
			buf[j++]='n';
			k=j;
			lcnt++;
			m=0;
			continue;
		}
		if (c1==32)		//ANK-SPACE
		{
			buf[j++]=str[i];
			continue;
		}
		if (c1==129 && str[i+1]==64)	//KANZI-SPACE
		{
			buf[j++]=str[i++];
			buf[j++]=str[i];
			continue;
		}
		if ((129<=c1 && c1<=159) || (224<=c1))
		{
			buf[j++]=str[i++];
			buf[j++]=str[i];
			k=r=j;
			m=1;
			continue;
		}
		else
		{
			buf[j++]=str[i];
			k=r=j;
			m=1;
			continue;
		}
	}
	buf[r]=0;
	if (m)	//最後の改行の後にも文字があった
		lcnt++;

	strcpy(str, buf);
	free(buf);

	return lcnt;

}

/********************************************************************
  LineStrMixで作った文字列を解釈する (return=行数) ここでは空白の圧縮はしない
 *******************************************************************/
int LineStrSep(char* str, const char* lfcode)
{
	int i,j,m,len,c1,lcnt;
	char* buf;

	len = strlen(str);
	buf = (char*)malloc(len*2+1);
	for (i=j=m=lcnt=0; i<len; i++)
	{
		c1 = str[i]; if (c1<0) c1+=256;
		if (c1==92 && str[i+1]==110)		//\n
		{
			strcpy(buf+j, lfcode);
			j+=strlen(lfcode);
			lcnt++;
			i++;
			m=0;
			continue;
		}
		if ((129<=c1 && c1<=159) || (224<=c1))
		{
			buf[j++]=str[i++];
			buf[j++]=str[i];
			m=1;
			continue;
		}
		else
		{
			buf[j++]=str[i];
			m=1;
			continue;
		}
	}
	buf[j]=0;
	if (m)	//最後の改行の後にも文字があった
		lcnt++;

	strcpy(str, buf);
	free(buf);

	return lcnt;

}




以下は試作品である。何かの必要にかられて一時的に作ったものであり、まだ 汎用ルーチンとしては仕上がっていない。参考までに。 ■csv操作関係 char* my_csvpack(const char* str); char* my_csvtok(char* str); long my_csvtokL(char* str); /******************************************************************** * CSV文字列操作 *******************************************************************/ char* my_csvpack(const char* str) { static char buf[256]; int i,j,cnt,len; cnt=0; len = strlen(str); for (i=0; i<len; i++) { if (str[i]==34) cnt++; } // char* buf = new char[len+cnt+4]; buf[0]=34; for(i=0,j=1; i<len; i++) { if (str[i]==34) { buf[j++]=34; buf[j++]=34; } else buf[j++]=str[i]; } buf[j++]=34; buf[j]=0; // CString wstr = CString(buf); // delete [] buf; return buf; } char* my_csvtok(char* str) { static char work[256]; int k; char* q; char qst; char c1,c2; if (!str) str = my_strtok_ptr; k=0; /* Skip spaces */ while(*str==' ') str++; if (*str==0) { my_strtok_del = 0; my_strtok_ptr = str; return(0); } /* if quote ? */ if (*str==34 || *str==39) qst=*str++; else qst=0; q = str; /* loop */ loop1: c1=str[0]; c2=str[1]; if (qst) { if (c1==qst && c2==44) // quote + comma { my_strtok_ptr = str+2; goto owari; } if (c1==qst && c2==0) // quote + null { my_strtok_ptr = str+1; goto owari; } } else { if (c1==44) // comma { my_strtok_ptr = str+1; goto owari; } if (c1==0) // null { my_strtok_ptr = str; goto owari; } } work[k++]=c1; str++; // if ((c1>=0x080 && c1<=0x09f) || (c1>=0x0e0)) // dest[k++]=*sour++; if (c1==qst && c2==qst) str++; goto loop1; owari: work[k]=0; // if (k>0 && work[k-1]==qst) // work[k-1]=0; // if (c1) // my_strtok_ptr = str++; // else // my_strtok_ptr = str; /* cut spaces */ // while(k>0 && dest[k-1]==' ') // k--; // dest[k]=0; return(work); } long my_csvtokL(char* str) { return PickSuziS( my_csvtok(str) ); } ■strtokStr char* my_strtokStr(char* str, const char* del) //仮バージョン { int k; char* q; if (!str) str = my_strtok_ptr; while(InCha(del,strlen(del),*str)>=0) str++; if (*str==0) { my_strtok_del = 0; my_strtok_ptr = str; return(0); } if (*str==0x22) { str++; for(q=str; *q!=0x22 && *q!=0;) q++; *q++=0; my_strtok_ptr = q+1; my_strtok_del = *q; return(str); } for (q=str; *q; q++) { k = InCha(del, strlen(del), *q); if (k>=0) { my_strtok_del = del[k]; my_strtok_ptr = q+1; *q = 0; return(str); } } my_strtok_del = 0; my_strtok_ptr = q; return(str); } ■septok char* my_septok(char* str, char* del) { int k; char* q; if (!str) str = my_strtok_ptr; if (*str==0) { my_strtok_del = 0; my_strtok_ptr = str; return(0); } for (q=str; *q; q++) { k = InCha(del, strlen(del), *q); if (k>=0) { my_strtok_del = del[k]; my_strtok_ptr = q+1; *q = 0; return(str); } } my_strtok_del = 0; my_strtok_ptr = q; return(str); } long my_septokL(char* str, char* del) { return PickSuziS(my_septok(str, del)); }

↑
(C)copyright ffortune.net 1995-2007 produced by ffortune and Lumi.
お問い合わせはこちらから