ページ 11

文字列を文字(文字列)にする

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
>フリオさん たかぎさん
複雑というか、こみいった処理をこれだけスマートにできるとは・・・
す、すごすぎる

プログラムをマスターすると
このくらいの処理も簡単なのですね
頭のつくりが違いすぎる・・・

助言ありがとうございました