¿Cómo puedo HTML- / URL-Encode un std :: wstring que contiene caracteres Unicode?

Tengo otra pregunta todavía. Si tuviera un std :: wstring con el siguiente aspecto:

たド た た た た た た た た た た た た た た た た た た た た た た た た た た た た た.

¿Cómo podría obtener URL codificada ( % nn , n = 0-9, af) para:

% E3% 83% 89% E3% 82% A4% E3% 83% 84% E8% AA% 9E% E3% 81% A7% E6% A4% 9C% E7% B4% A2% E3% 81% 97% E3 % 81% A6% E3% 81% 84% E3% 81% A6% E3% 81% 93% E3% 81% A1% E3% 82% 89% E3% 81% AE% E3% 82% B5% E3% 82 % A4% E3% 83% 88% E3% 81% AB% E3% 81% 9F% E3% 81% A9% E3% 82% 8A% E7% 9D% 80% E3% 81% 8D% E3% 81% BE % E3% 81% 97% E3% 81% 9F% E3% 80% 82

… y también HTML-Encoded ( & # nnn ( nn ) ;, n = 0-9 (?)) a:

たド た た た た た た た た た た た た た た た た た た た た た た た た た た た た た.

Por favor, ayúdenme ya que estoy totalmente perdido ahora y ni siquiera sé por dónde empezar. Por cierto, el rendimiento no es muy importante para mí en este momento.

¡Gracias por adelantado!

Aquí hay un ejemplo que muestra dos métodos, uno basado en la biblioteca de Qt y otro basado en la biblioteca de la ICU. Ambos deberían ser bastante independientes de la plataforma:

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  void encodeQt() { const QString str = QString::fromWCharArray(L"ドイツ語で検索していてこちらのサイトにたどり着きました。"); const QUrl url = str; std::cout << "URL encoded: " << url.toEncoded().constData() << std::endl; typedef QVector CodePointVector; const CodePointVector codePoints = str.toUcs4(); std::stringstream htmlEncoded; for (CodePointVector::const_iterator it = codePoints.constBegin(); it != codePoints.constEnd(); ++it) { htmlEncoded << "&#" << *it << ';'; } std::cout << "HTML encoded: " << htmlEncoded.str() << std::endl; } void encodeICU() { const std::wstring cppString = L"ドイツ語で検索していてこちらのサイトにたどり着きました。"; int bufSize = cppString.length() * 2; boost::scoped_array strBuffer(new UChar[bufSize]); int size = 0; UErrorCode error = U_ZERO_ERROR; u_strFromWCS(strBuffer.get(), bufSize, &size, cppString.data(), cppString.length(), &error); if (error) return; const UnicodeString str(strBuffer.get(), size); bufSize = str.length() * 4; boost::scoped_array buffer(new char[bufSize]); u_strToUTF8(buffer.get(), bufSize, &size, str.getBuffer(), str.length(), &error); if (error) return; const std::string urlUtf8(buffer.get(), size); std::stringstream urlEncoded; urlEncoded << std::hex << std::setfill('0'); for (std::string::const_iterator it = urlUtf8.begin(); it != urlUtf8.end(); ++it) { urlEncoded << '%' << std::setw(2) << static_cast(static_cast(*it)); } std::cout << "URL encoded: " << urlEncoded.str() << std::endl; std::stringstream htmlEncoded; StringCharacterIterator it = str; while (it.hasNext()) { const UChar32 pt = it.next32PostInc(); htmlEncoded << "&#" << pt << ';'; } std::cout << "HTML encoded: " << htmlEncoded.str() << std::endl; } int main() { encodeQt(); encodeICU(); } 

Verá, antes de poder convertir un char a una secuencia de escape de URL, debe convertir su wstring * en un conjunto de caracteres ISO-Latin, que es lo que se utiliza para las URL. La ICU podría ser un buen lugar para comenzar, donde puedes pasar tu Wstring y obtener una secuencia ISO-Lantin. Luego, simplemente itere a través de los caracteres resultantes y conviértalos a la senal de escape:

 std::stringstream URL; URL << std::hex; for(auto it = myWString.begin(); it != myWString.end(); ++it) URL << '%' << std::setfill('0') << std::setw(2) << (int)*it; 

Mire aquí para obtener más información sobre cómo formatear la cadena.

* Asumo que tu wstring es un UTF-16, que generalmente es el caso, aunque no especificaste

Esto también podría ayudar.

Aquí hay una versión que convierte desde UTF-16 (wchar) a UTF-8 con encoding hexadecimal usando la función WideCharToMultiByte () específica de Win32.

 #include  #include  #include  #include  std::string wstring_to_utf8_hex(const std::wstring &input) { std::string output; int cbNeeded = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, NULL, 0, NULL, NULL); if (cbNeeded > 0) { char *utf8 = new char[cbNeeded]; if (WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, utf8, cbNeeded, NULL, NULL) != 0) { for (char *p = utf8; *p; *p++) { char onehex[5]; _snprintf(onehex, sizeof(onehex), "%%%02.2X", (unsigned char)*p); output.append(onehex); } } delete[] utf8; } return output; } int main(int, char*[]) { std::wstring ja = L"ドイツ語で検索していてこちらのサイトにたどり着きました。"; std::cout << "result=" << wstring_to_utf8_hex(ja) << std::endl; return 0; } 

Para ir por el otro camino, necesitarás usar algunos análisis para decodificar los valores hexadecimales en un buffer UTF-8, y luego llamar al MultiByteToWideChar () complementario para volver a ponerlo en una matriz wchar.

 #include  #include  #include  #include  #include  #include  std::string unhexlify(const std::string &input) { std::string output; for (const char *p = input.c_str(); *p; ) { if (p[0] == '%' && isxdigit(p[1]) && isxdigit(p[2])) { int ch = (isdigit(p[1]) ? p[1] - '0' : toupper(p[1]) - 'A' + 10) * 16 + (isdigit(p[2]) ? p[2] - '0' : toupper(p[2]) - 'A' + 10); output.push_back((char)ch); p += 3; } else if (p[0] == '%' && p[1] == '#' && isdigit(p[2])) { int ch = atoi(p + 2); output.push_back((char)ch); p += 2; while (*p && isdigit(*p)) p++; if (*p == ';') p++; } else { output.push_back(*p++); } } return output; } std::wstring utf8_hex_to_wstring(const std::string &input) { std::wstring output; std::string utf8 = unhexlify(input); int cchNeeded = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0); if (cchNeeded > 0) { wchar_t *widebuf = new wchar_t[cchNeeded]; if (MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, widebuf, cchNeeded) != 0) { output = widebuf; } delete[] widebuf; } return output; } int main(int, char*[]) { std::wstring ja = L"ドイツ語で検索していてこちらのサイトにたどり着きました。"; std::string hex = "%E3%83%89%E3%82%A4%E3%83%84%E8%AA%9E%E3%81%A7%E6%A4%9C%E7%B4%A2%E3%81%97%E3%81%A6%E3%81%84%E3%81%A6%E3%81%93%E3%81%A1%E3%82%89%E3%81%AE%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AB%E3%81%9F%E3%81%A9%E3%82%8A%E7%9D%80%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82"; std::wstring newja = utf8_hex_to_wstring(hex); std::cout << "match?=" << (newja == ja ? "yes" : "no") << std::endl; return 0; } 

Primero, conviértase en UTF-8. Entonces, la encoding URL / HTML normal haría lo correcto.