2016-12-13 6 views
1

Мне нужно работать со строками, которые содержат кодировки URL, такие как «% C3% A7», и мне нужно преобразовать эти последовательности в соответствующие печатные символы. Поэтому я написал функцию. Это работает, но это кажется довольно неудобным. Я абсолютный начинающий C/C++. Возможно, кто-то может указать мне на более элегантное решение, пожалуйста.Преобразование кодировки URL для печатных символов

#include <iostream> 

using namespace std; 

static inline void substitute_specials(string &str) { 
    const struct {string from,to;} substitutions[] { { "20"," " },{ "24","$" },{ "40","@" },{ "26","&" },{ "2C","," },{ "C3%A1","á" },{ "C3%A7","ç" },{ "C3%A9","é" } }; 
    size_t start_pos = 0; 
    while ((start_pos = str.find("%", start_pos)) != string::npos) { 
     start_pos++; 
     for (int i=0; i< extent < decltype(substitutions) > ::value; i++) { 
      if (str.compare(start_pos,substitutions[i].from.length(),substitutions[i].from) == 0) { 
        str.replace(start_pos-1, substitutions[i].from.length()+1, substitutions[i].to); 
        start_pos += substitutions[i].to.length()-1; 
       break; 
      } 
     } 
    } 
} 

int main() { 
    string testString = "This%20is %C3%A1 test %24tring %C5ith %40 lot of spe%C3%A7ial%20charact%C3%A9rs%2C %26 worth many %24%24%24"; 
    substitute_specials(testString); 
    cout << testString << "\n"; 
    return 0; 
} 

EDIT 26.12.2016: Я до сих пор застрял с этой проблемой. Я нашел несколько предложений для библиотек и некоторых написанных вручную функций, но если они вообще выполняются, они будут только декодировать% xx (2-байтовый шестнадцатеричный код в строке), например% 20 = пробел. Я не нашел ничего, что бы сделать 4 байтовый код, например% C3% 84 = Ä, и я не смог его изменить. Также curl_easy_unescape library() запрашивает 2 байтовых кода. Я нашел именно то, что мне нужно, доступно в javascript, соответствующие функции - encodeURI()/decodeURI(), см. http://www.w3schools.com/tags/ref_urlencode.asp. Источник decodeURI() C/C++, вероятно, решит мою проблему. Строка 3829 в https://dxr.mozilla.org/mozilla-central/source/js/src/jsstr.cpp выглядит как реализация этого, но я не могу извлечь то, что мне нужно. Из других примеров, которые я нашел: многие используют sscanf для преобразования шестибайтового кода в 2 байта в int, используя формат% x hex, а затем static_castint для получения правильного символа. Как я могу изменить это для 4-байтовых последовательностей? Текущее состояние моей функции

wstring url_decode2(char* SRC) { 

wstring ret; 
wchar_t ch; 
int i, ii; 
char sub[5]; 

for (i=0; i<strlen(SRC); i++) { 
    if (SRC[i]=='%') { 
     if ((SRC[i+3]=='%') && (SRC[i+1]>='A')) { 
      sub[0]=SRC[i+4]; 
      sub[1]=SRC[i+5]; // (also tried lsb/msb) 
      sub[2]=SRC[i+1]; // skip +3, it's % 
      sub[3]=SRC[i+2]; // 
      sub[4]='\0'; 
      i=i+5; 
     } else { 
      sub[0]=SRC[i+1]; 
      sub[1]=SRC[i+2]; 
      sub[2]='\0'; 
      i=i+2; 
     } 
     sscanf(&sub[0], "%x", &ii); 
     ch=static_cast<wchar_t>(ii); 
     ret+=ch; 
    } else 
     ret+=SRC[i]; 

} 
return ret; 

}

Может кто-нибудь помочь мне, пожалуйста?

+1

Это * не * UTF8 «кодировки». Это URL (?) Escape-последовательностей. То, что вы видите на этой странице, это символы UTF8. В UTF8 символы ASCII отображаются одинаково, символы, отличные от ASCII, используют 2 или более байта для хранения, но отображаются как один символ. Вам нужен метод декодирования URL. –

+0

BTW [литералы UTF8] (http://en.cppreference.com/w/cpp/language/string_literal) нуждаются в префиксе 'u8', например' u8 "Δx =%" '. Или прямо в строку 'auto testString = u8 'Δx =%" s; 'или' string testString = u8 "Δx =%" s; ' –

+0

[Страница MSDN в литералах строк и символов] (https://msdn.microsoft .com/en-us/library/69ze775t.aspx) объясняет, как очень удобно использовать UTF8, UTF16 и т. д. на C++. –

ответ

 Смежные вопросы

  • Нет связанных вопросов^_^