■ エスケープ文字を使って文字列変換
/*
* c_str.c : エスケープ文字を使って文字列変換
*
* Copyright (c) 2002 AOK.
*
* 2002.12.11 - 初版
*
* かなり使い道があると思うのは僕だけかな…
*
*/
#include <stdio.h>
#include <stdlib.h>
/*
* 入力文字列をCスタイルの文字列に変換。
* dst を NULL にして必要なバッファサイズ(NULL文字を含まない)
* を求め、dst の領域確保を行うこと。
*/
int c_escape(char *src, char *dst)
{
unsigned char c;
int mode = 0, cnt = 0;
while (*src != '\0')
{
c = (unsigned char)*src++;
switch (mode)
{
case 0:
switch (c)
{
case '\t': if (dst != NULL) { *dst++ = '\\'; *dst++ = 't'; } cnt+=2; break;
case '\n': if (dst != NULL) { *dst++ = '\\'; *dst++ = 'n'; } cnt+=2; break;
case '\r': if (dst != NULL) { *dst++ = '\\'; *dst++ = 'r'; } cnt+=2; break;
case '\\': if (dst != NULL) { *dst++ = '\\'; *dst++ = '\\';} cnt+=2; break;
case '\"': if (dst != NULL) { *dst++ = '\\'; *dst++ = '\"';} cnt+=2; break;
default:
if ((c>=0x81 && c<=0x9F) || (c>=0xE0 && c<=0xFC)) mode = 1;
if (dst != NULL) *dst++ = c;
cnt++;
break;
}
break;
case 1:
if (dst != NULL) *dst++ = c;
cnt++;
mode = 0;
break;
default:
break;
}
}
if (dst != NULL) *dst = '\0';
return cnt;
}
/*
* Cスタイルの文字列を元の文字列に戻す。
* dst を NULL にして必要なバッファサイズ(NULL文字を含まない)
* を求め、dst の領域確保を行うこと。
*/
int c_unescape(char *src, char *dst)
{
unsigned char c;
int mode = 0, cnt = 0;
while (*src != '\0')
{
c = (unsigned char)*src++;
switch (mode)
{
case 0:
if (c == '\\') { mode = 2; break; }
if ((c>=0x81 && c<=0x9F) || (c>=0xE0 && c<=0xFC)) mode = 1;
if (dst != NULL) *dst++ = c;
cnt++;
break;
case 1:
if (dst != NULL) *dst++ = c;
cnt++;
mode = 0;
break;
case 2:
if (dst != NULL)
{
switch (c)
{
case 't': *dst++ = '\t'; break;
case 'n': *dst++ = '\n'; break;
case 'r': *dst++ = '\r'; break;
case '\\': *dst++ = '\\'; break;
case '\"': *dst++ = '\"'; break;
default: *dst++ = c; break;
}
}
cnt++;
mode = 0;
break;
default:
break;
}
}
if (dst != NULL) *dst = '\0';
return cnt;
}
/* テスト */
int main()
{
int n;
char p1[32767], *p2, *p3;
fgets(p1, 32767, stdin);
/* エスケープする */
n = c_escape(p1, NULL);
printf("escape: <%d>\n", n);
p2 = (char *)malloc(n+1);
c_escape(p1, p2);
/* アンエスケープする */
n = c_unescape(p2, NULL);
printf("unescape: <%d>\n", n);
p3 = (char *)malloc(n+1);
c_unescape(p2, p3);
/* 表示 */
printf("%s\n", p1);
printf("%s\n", p2);
printf("%s\n", p3);
free(p2);
free(p3);
return 0;
}