2011-08-26 4 views
2

그래서 우리는 have 같은 기능 :하지만 창문내`std :: string url_encode_wstring (const std :: wstring & input)`을 리눅스에서 어떻게 만드나요?

std::string url_encode_wstring(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; 
    } 

그 화격자는 내가 궁금해 (그리고 가능)가 리눅스에서 작동되도록하려면?

+1

'wcstombs'와'mbstowcs'를 사용하십시오. 몇 가지 예제 코드는 [이 대답에] (http://stackoverflow.com/questions/7141260/compare-stdwstring-and-stdstring/7159944#7159944)를보십시오. –

답변

3

IMHO 휴대용 문자 코덱 라이브러리를 사용해야합니다. 다음은 iconv를 사용하는 최소한의 이식 가능한 코드의 예입니다. 충분해야합니다. Windows에서 작동해야합니다 (있는 경우 Windows 관련 코드를 모두 제거 할 수 있음). wcstombs & co 함수 (https://www.gnu.org/s/hello/manual/libc/iconv-Examples.html) 을 사용하지 않도록 GNU 지침을 준수합니다. 사용 사례에 따라 적절하게 오류를 처리하고 성능을 향상 시키려면 클래스를 만들면됩니다.

#include <iostream> 

#include <iconv.h> 
#include <cerrno> 
#include <cstring> 
#include <stdexcept> 

std::string wstring_to_utf8_string(const std::wstring &input) 
{ 
    size_t in_size = input.length() * sizeof(wchar_t); 
    char * in_buf = (char*)input.data(); 
    size_t buf_size = input.length() * 6; // pessimistic: max UTF-8 char size 
    char * buf = new char[buf_size]; 
    memset(buf, 0, buf_size); 
    char * out_buf(buf); 
    size_t out_size(buf_size); 
    iconv_t conv_desc = iconv_open("UTF-8", "wchar_t"); 
    if (conv_desc == iconv_t(-1)) 
     throw std::runtime_error(std::string("Could not open iconv: ") + strerror(errno)); 
    size_t iconv_value = iconv(conv_desc, &in_buf, &in_size, &out_buf, &out_size); 
    if (iconv_value == -1) 
     throw std::runtime_error(std::string("When converting: ") + strerror(errno)); 
    int ret = iconv_close(conv_desc); 
    if (ret != 0) 
     throw std::runtime_error(std::string("Could not close iconv: ") + strerror(errno)); 
    std::string s(buf); 
    delete [] buf; 
    return s; 
} 


int main() { 
    std::wstring in(L"hello world"); 
    std::wcout << L"input: [" << in << L"]" << std::endl; 
    std::string out(wstring_to_utf8_string(in)); 
    std::cerr << "output: [" << out << "]" << std::endl; 
    return 0; 
} 
+0

IMHO'wctombs '에 대한 많은 반대 의견은'std :: locale'과 co. 그러나'iconv '를 사용하는 것은 좋은 조언이다. – jpalecek

관련 문제