バッファは動的確保の方がいいと思います。
前のプログラムはマルチスレッドに対応していないかもしれません。
動的確保したらちゃんと解放しましょう。
どちらも無駄は大したことはありません。
メモリを無駄にするバージョン(必ず入力の3倍のメモリを確保します。)
コード:
char* URLEncode(char *str)
{
const unsigned char buf[] = "0123456789ABCDEF";
unsigned char* out_buf;
int pos;
int i;
pos=0;
out_buf=calloc(sizeof(char),strlen(str)*3+1);
while(*str != '\0')
{
i = 0;
if((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z') || *str == '@' || *str == '*' || *str == '-' || *str == '.' || *str == '_')
{
i = 0;
}
else
{
i = 1;
}
if(i == 1)
{
out_buf[pos++] = '%';
out_buf[pos++] = buf[(unsigned char)*str >> 4];
out_buf[pos++] = buf[(unsigned char)*str & 0x0F];
}
else
{
out_buf[pos++] = *str;
}
str++;
}
out_buf[pos] = '\0';
return out_buf;
}
時間を無駄にするバージョン(約2倍の時間がかかります。)
コード:
char* URLEncode(char *str)
{
const unsigned char buf[] = "0123456789ABCDEF";
unsigned char* out_buf;
char* strbak;
int pos;
int i;
strbak=str;
pos=0;
while(*str != '\0')
{
if((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z') || *str == '@' || *str == '*' || *str == '-' || *str == '.' || *str == '_')
{
pos++;
}
else
{
pos+=3;
}
str++;
}
out_buf=calloc(sizeof(char),pos+1);
str=strbak;
pos=0;
while(*str != '\0')
{
i = 0;
if((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z') || *str == '@' || *str == '*' || *str == '-' || *str == '.' || *str == '_')
{
i = 0;
}
else
{
i = 1;
}
if(i == 1)
{
out_buf[pos++] = '%';
out_buf[pos++] = buf[(unsigned char)*str >> 4];
out_buf[pos++] = buf[(unsigned char)*str & 0x0F];
}
else
{
out_buf[pos++] = *str;
}
str++;
}
out_buf[pos] = '\0';
return out_buf;
}
共通する使用プログラム
コード:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*前述のURLEncode関数のいずれか*/
int main(void) {
char in[300];
char* out;
fgets(in,sizeof(in),stdin);
if(strstr(in,"\n")!=NULL)*strstr(in,"\n")=0;
out=URLEncode(in);
printf("%s\n",out);
free(out);
return 0;
}
というか二つのif文は一つにまとめたほうがいいと思います。
メモリを無駄にするバージョン
コード:
char* URLEncode(char *str)
{
const unsigned char buf[] = "0123456789ABCDEF";
unsigned char* out_buf;
int pos;
pos=0;
out_buf=calloc(sizeof(char),strlen(str)*3+1);
while(*str != '\0')
{
if((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z') || *str == '@' || *str == '*' || *str == '-' || *str == '.' || *str == '_')
{
out_buf[pos++] = *str;
}
else
{
out_buf[pos++] = '%';
out_buf[pos++] = buf[(unsigned char)*str >> 4];
out_buf[pos++] = buf[(unsigned char)*str & 0x0F];
}
str++;
}
out_buf[pos] = '\0';
return out_buf;
}
時間を無駄にするバージョン
コード:
char* URLEncode(char *str)
{
const unsigned char buf[] = "0123456789ABCDEF";
unsigned char* out_buf;
char* strbak;
int pos;
strbak=str;
pos=0;
while(*str != '\0')
{
if((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z') || *str == '@' || *str == '*' || *str == '-' || *str == '.' || *str == '_')
{
pos++;
}
else
{
pos+=3;
}
str++;
}
out_buf=calloc(sizeof(char),pos+1);
str=strbak;
pos=0;
while(*str != '\0')
{
if((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z') || *str == '@' || *str == '*' || *str == '-' || *str == '.' || *str == '_')
{
out_buf[pos++] = *str;
}
else
{
out_buf[pos++] = '%';
out_buf[pos++] = buf[(unsigned char)*str >> 4];
out_buf[pos++] = buf[(unsigned char)*str & 0x0F];
}
str++;
}
out_buf[pos] = '\0';
return out_buf;
}