ページ 1 / 1
文字列を文字(文字列)にする
Posted: 2010年7月21日(水) 19:30
by dic
タイトルの通りなのですが、char string[80]内にある文字列
abcd%20efgh%20ijklm%20kalkj
というものが代入されているとして
この文字列の %20 を _ に変換したいのですが
str...関数でこのような関数はあるのでしょうか?
自分では見つけれなかったので
なかったら自作するしかないので
あったらその関数を使おうかなと思ってます
str系でなくてもいいです
環境:WindowsXP, Visual C++ 6.0
制限:特になし
Re:文字列を文字(文字列)にする
Posted: 2010年7月21日(水) 20:58
by softya
abcd%20efgh%20ijklm%20kalkj はURLエンコードされている文字列だと思いますが、C言語の標準関数ではURLデコードできる関数は無いですね。ちなみに%20は0x20の事なので半角空白だと思います。
デコード方法の参考。
http://www.kinet.or.jp/hiromin/cgi_intr ... ncode.html
Re:文字列を文字(文字列)にする
Posted: 2010年7月21日(水) 21:51
by ISLe
str系で文字列を探すのはstrstrです。
でも%見付けて続く数字を処理するのがよろしいですね。
--追記
質問は変換までできる関数はないかってことでしたね。
正規表現ライブラリとかになってしまいますかね。

Re:文字列を文字(文字列)にする
Posted: 2010年7月22日(木) 15:51
by dic
>softyaさん
そうです URLの空白文字が%20になるので、変換できる関数がC/C++にあるのかなぁと思ってたのですが
ないみたいですね
自作も・・・かなり、難しいレベルに入ります(私の少ない知能では)
%だけを_に変換する自作関数を作ります
参考のリンク先サイトは
私の頭では理解が・・・orz
勉強を頑張りたいと思います
>ISLeさん
たしかにstrstrで%のところをヒットさせて処理する・・・って形になるのですが
なかなかアルゴリズムが考えつきません
なので %20 を _20 に変換して、これでよしとしました
正規表現は・・・あつかったことないので、分からないですね
boostとかにあるんでしょうか?
まだ、boostいじってないので良く分かってません
参考本が少なく値段も結構するので、手がでないです
回答ありがとうございました

Re:文字列を文字(文字列)にする
Posted: 2010年7月22日(木) 17:34
by フリオ
とりあえず、単純に文字列を置き換えるだけなら、
#include <stdio.h>
#include <string.h>
char *replace(char *s1, const char *s2, const char *s3)
{
size_t l2 = strlen(s2), l3 = strlen(s3);
if(l2){
char *p;
for(p = s1; p = strstr(p, s2); p += l3){
memmove(p + l3, p + l2, strlen(p + l2) + 1);
memcpy(p, s3, l3);
}
}
return s1;
}
int main(void)
{
char s[128] = "abcd%20efgh%20ijklm%20kalkj";
puts(s);
puts(replace(s, "%20", "_"));
puts(replace(s, "", "%20"));
puts(replace(s, "_", "%20"));
puts(replace(s, "%20", ""));
return 0;
}
Re:文字列を文字(文字列)にする
Posted: 2010年7月22日(木) 18:47
by フリオ
%**を'\x**'に置き換えるプログラムを考えてみました。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *func(char *s)
{
char *p;
for(p = s; p = strchr(p, '%'); ++ p){
char hex[3], *e;
int c;
hex[0] = *(p + 1); hex[1] = *(p + 2); hex[2] = '\0';
c = strtol(hex, &e, 16);
if(!*e){
memmove(p + 1, p + 3, strlen(p + 3) + 1);
*p = c;
}
}
return s;
}
int main(void)
{
char s[128] = "%61%62%63%64%20%65%66%67%68%20%69%6a%6b%6c%6d%20%6e%6f%70%71";
puts(s);
puts(func(s));
return 0;
}
一回一回後ろ全部をずらすのは効率が悪いので、たかぎさんのを参考にfuncを書き換えました。
char *func(char *s)
{
char *p, *q;
for(p = q = s; *p = *q; ++ p, ++ q){
if(*p == '%'){
char hex[3], *e;
int c;
hex[0] = *++ q; hex[1] = *++ q; hex[2] = '\0';
c = strtol(hex, &e, 16);
if(!*e) *p = c;
else q -= 2;
}
}
return s;
}

Re:文字列を文字(文字列)にする
Posted: 2010年7月22日(木) 18:49
by たかぎ
エラーチェックはしていませんが...
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char string[80] = "abcd%20efgh%20ijklm%20kalkj";
char *s1, *s2;
int c;
for (s1 = s2 = string; (c = *s2) != '\0'; s1++, s2++)
{
if (c != '%')
{
*s1 = c;
}
else
{
c = (unsigned char)s2[1];
*s1 = (isdigit(c) ? (c - '0') : (tolower(c) - 'a' + 10)) << 4;
c = (unsigned char)s2[2];
*s1 |= (isdigit(c) ? (c - '0') : (tolower(c) - 'a' + 10));
s2 += 2;
}
}
*s1 = '\0';
puts(string);
return 0;
}
こんな感じでよいのでは?
Re:文字列を文字(文字列)にする
Posted: 2010年7月23日(金) 16:52
by dic
>フリオさん たかぎさん
複雑というか、こみいった処理をこれだけスマートにできるとは・・・
す、すごすぎる
プログラムをマスターすると
このくらいの処理も簡単なのですね
頭のつくりが違いすぎる・・・
助言ありがとうございました