// //【関数 ESCの機能】 // // C言語のエスケープ文字列を1個の文字コードに変換し // エスケープ文字列の文字数を返却する。 // エスケープ文字列でない場合、先頭文字そのものを返し、 // 文字数は1が返却される。 // // [呼び出し形式] int ESC(ch, &DT) // unsigned char ch[] : エスケープ文字列(例:\\, \n, \123, \x1A) // unsigned char *DT : 返却文字(エスケープ文字列でない場合先頭 1 文字) // 関数戻り値 : エスケープ文字列の文字数 // (エスケープ文字列でない場合 1) // #include "stdafx.h" int extOctal(unsigned char ch[], unsigned char *DT){// 8進数 int i, D;// 8進数でないコードが検出するまで処理(最大3文字:先頭は必ず8進数となる) for(i=0, D=0; (i<3) &&(ch[i]>='0' && ch[i]<='7'); i++) D = D * 8 + ch[i] - '0'; *DT=(unsigned char) D; return i; } int extHexa(unsigned char ch[], unsigned char *DT){// 16進数 int i, D;// 16進数でないコードが検出するまで処理(最大2文字) for(i=0, D=0; i<2; i++){ if (ch[i]>='0' && ch[i]<='7') D = D*16 + ch[i] - '0'; else if(ch[i]>='a' && ch[i]<='f') D = D*16 + ch[i] - 'a' + 10; else if(ch[i]>='A' && ch[i]<='F') D = D*16 + ch[i] - 'A' + 10; else break; } *DT=(unsigned char) D; return i; // 先頭が16進数でない場合、DT、返却値共に 0 となる } int ESC(unsigned char ch[], unsigned char *DT){ int i; unsigned char tb[]={'a' , 'b' , 'f' , 'n' , 'r' , 't' , 'v' , '\\', '\'', '\"', '?' , 0 }; unsigned char vc[]={0x07, 0x08, 0x0C, 0x0A, 0x0D, 0x09, 0x0B, 0x5C, 0x27, 0x22, 0x3F, 0}; if(ch[0]!='\\') {*DT=ch[0]; return 1;} // 先頭が\でない場合 if(ch[1]>='0' && ch[1]<='7') return extOctal(ch+1,DT) + 1; // 8進数の場合 char ch1=ch[1]; if(ch1>='A' && ch1<='Z') ch1=(ch1-'A')+'a'; // 大文字を小文字に変換 if(ch1=='x'){if((i=extHexa(ch+2,DT))==0) *DT=ch[1]; return i + 2;} // 16進数の場合 for(i=0;tb[i]!=0;i++) if(tb[i]==ch1) { *DT=vc[i]; return 2;} // 標準エスケープ文字 *DT=ch[1]; return 2; // \の後の文字が標準でないとき(便宜上) } int _tmain(int argc, _TCHAR* argv[])// テストメイン([CTRL]Zで終了する) { // コンソール入力のエスケープ文字列を単一文字に変換して、単一文字を16進数表現で表示する。 unsigned char X[256], DT; int i; while(scanf("%s",X)!=EOF){i = ESC(X, &DT);printf("i=%d %s[%02X]\n",i, X,DT);} return 0; }