На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Преобразование std::string в std::wstring туда и обратно, как делается?
    Преобразование std::string в std::wstring туда и обратно, как делается? (Юникод <-> Анси)
    Сообщение отредактировано: Alca -
      ExpandedWrap disabled
           std::string str = "12345";
           std::wstring wstr1(str.begin(), str.end());
         
           std::wstring wstr2(str.length(), ' ');
           std::copy(str.begin(), str.end(), wstr2.begin());
         
           std::string str1(wstr1.begin(), wstr1.end());
         
           std::string str2(wstr2.length(), L' ');
           std::copy(wstr2.begin(), wstr2.end(), str2.begin());
        а если юникодная строка (std::wstring) содержит иероглифы? Как ее переводить в std::string? Или это бред?

        Вообще мне надо конвертить строки для сокетных функций, типа такого плана:
        ExpandedWrap disabled
          #if defined(UNICODE) || defined(_UNICODE)
              typedef std::wstring        tstring;        
          #else  
              typedef std::string         tstring;      
          #endif  /*_UNICODE*/

        ExpandedWrap disabled
          BOOL CXSocket::bConnect(const std::tstring &csIp, USHORT usPort) {
              INT iRes = etError;
              
          #if defined(UNICODE) || defined(_UNICODE)
              //конвертим в АНСИ
              //csIp -> std::wstring
          #else  
              //это АНСИ-строка, ничего с ней не делаем
          #endif  /*_UNICODE*/
              
              struct sockaddr_in saSockAddr = {0};          
              saSockAddr.sin_family      = AF_INET;
              saSockAddr.sin_addr.s_addr = inet_addr(csIp.c_str());  
              saSockAddr.sin_port        = ::htons(usPort);
           
              iRes = ::connect(_m_puiSocket, (struct sockaddr *)&saSockAddr, sizeof(struct sockaddr_in));  
              /*DEBUG*/XASSERT_RET(0 == iRes, FALSE);
           
              return TRUE;  
          }
        Сообщение отредактировано: Alca -
          Цитата Alca @
          а если юникодная строка (std::wstring) содержит иероглифы? Как ее переводить в std::string? Или это бред?

          выдели размер равный юникодовой строке и копируй, как выше показал

          Добавлено
          Или тебе важно соблюсти кодировку ?
            Вот в этом проекте: http://www.sources.ru/wiki/doku.php?id=projects:ufo есть соответствующие специализации lexical_cast
              Цитата
              Или тебе важно соблюсти кодировку ?

              Скорее всего, чтоб независимо от входной строки (Юникод или Анси) в сокетную функцию заходила Ансишная строка.
                Цитата
                Вот в этом проекте: http://www.sources.ru/wiki/doku.php?id=projects:ufo есть соответствующие специализации lexical_cast

                в упор не вижу
                Сообщение отредактировано: Alca -
                  Может Флекс там и переделал чего. Было в GOAL/include/lexical_cast.h
                    Там кроме бинарников я ничего нет

                    Добавлено
                    Это типа http://firstcontact.svn.sourceforge.net/viewvc/firstcontact/firstcontact/trunk/GOAL/include/lexical_cast.h?revision=116 ???
                      наверное.
                        Цитата Alca @
                        Преобразование std::string в std::wstring туда и обратно, как делается?

                        Стандартными средствами C++ примерно так можно:

                        ExpandedWrap disabled
                          #include <iostream>
                          #include <locale>
                          #include <string>
                          #include <vector>
                           
                          std::wstring wide_string(std::string const &s, std::locale const &loc)
                          {
                              if (s.empty())
                                  return std::wstring();
                              std::ctype<wchar_t> const &facet = std::use_facet<std::ctype<wchar_t> >(loc);
                              char const *first = s.c_str();
                              char const *last = first + s.size();
                              std::vector<wchar_t> result(s.size());
                              
                              facet.widen(first, last, &result[0]);
                              
                              return std::wstring(result.begin(), result.end());
                          }
                           
                          std::string narrow_string(std::wstring const &s, std::locale const &loc, char default_char = '?')
                          {
                              if (s.empty())
                                  return std::string();
                              std::ctype<wchar_t> const &facet = std::use_facet<std::ctype<wchar_t> >(loc);
                              wchar_t const *first = s.c_str();
                              wchar_t const *last = first + s.size();
                              std::vector<char> result(s.size());
                              
                              facet.narrow(first, last, default_char, &result[0]);
                              
                              return std::string(result.begin(), result.end());
                          }
                           
                          char const *russian_locale_designator = "rus"; // обозначение локали зависит от реализации,
                                                                         // "rus" подходит для VC++
                           
                          int main()
                          {
                              std::locale loc(russian_locale_designator);
                           
                              std::wstring const s  = L"русский текст";
                              std::string const  sa = ::narrow_string(s, loc);
                              std::wstring const sw = ::wide_string(sa, loc);
                                  
                              std::locale::global(loc);
                              
                              std::wcout << "original  wide: " << s  << std::endl;
                              std::cout  << "wide -> narrow: " << sa << std::endl;
                              std::wcout << "narrow -> wide: " << sw << std::endl;
                          }
                        Сообщение отредактировано: Masterkent -
                          Цитата Alca @
                          чтоб независимо от входной строки (Юникод или Анси) в сокетную функцию заходила Ансишная строка.
                          Цитата Alca @
                          а если юникодная строка (std::wstring) содержит иероглифы?
                          Надо определиться с кодировкой, в которой происходит обмен. Тогда и станет понятно, какие нужны преобразования.
                          Сообщение отредактировано: vst -
                            ExpandedWrap disabled
                               std::wstring CUSCError::char2wchar( const std::string & p_in, const std::locale & p_loc ) const
                                  {
                                      try{
                                          std::wstring out( p_in.length(), 0 );
                                          std::string::const_iterator i = p_in.begin(), ie = p_in.end();
                                          std::wstring::iterator j = out.begin();
                                          for( ; i!=ie; ++i, ++j )
                                              *j = std::use_facet< std::ctype< wchar_t > > ( p_loc ).widen( *i );
                                          return out;
                                      }catch(...)
                                      {
                                          return std::wstring();
                                      }
                                  };
                               
                                  std::string CUSCError::wchar2char( const std::wstring & p_in, const std::locale & p_loc ) const
                                  {
                                      typedef std::wstring::traits_type::state_type       TsType;
                                      typedef std::codecvt<wchar_t, char, TsType>         Tcvt;
                               
                                      try{
                                          std::string     l_out( p_in.length(), char() );
                                          const Tcvt &    l_cvt = std::use_facet<Tcvt>(p_loc);
                                          const wchar_t*  l_from_nxt;
                                          char*           l_to_nxt;
                                          TsType          l_state = TsType();
                                          l_cvt.out(l_state, &p_in[0], &p_in[0] + p_in.size(), l_from_nxt, &l_out[0], &l_out[0] + l_out.size(), l_to_nxt);
                                          return l_out;
                                      }catch(...)
                                      {
                                          return std::string();
                                      }        
                                  };


                            Не знаю на сколько это правильно но делаю так.
                              Ну и мои 5 копеек:
                              ExpandedWrap disabled
                                std::wstring char2wchar(const std::string& p_in, const std::locale& p_loc)
                                {
                                 try
                                 {
                                  const std::ctype<wchar_t>& ctypeFacet = std::use_facet<std::ctype<wchar_t> >(p_loc);
                                        std::wstring         out(p_in.length(), L'\0');
                                 
                                  std::transform(p_in.begin(), p_in.end(), out.begin(), boost::bind(boost::mem_fn(
                                         static_cast<wchar_t (std::ctype<wchar_t>::*)(char) const>(&std::ctype<wchar_t>::widen)
                                                                                                                 ),
                                                                                                    &ctypeFacet, _1));
                                  return out;
                                 }
                                 catch(...)
                                 {
                                  return std::wstring();
                                 }
                                };
                                 
                                std::string wchar2char(const std::wstring& p_in, const std::locale& p_loc, char def='?')
                                {
                                 try
                                 {
                                  const std::ctype<wchar_t>& ctypeFacet = std::use_facet<std::ctype<wchar_t> >(p_loc);
                                        std::string          out(p_in.length(), '\0');
                                 
                                  std::transform(p_in.begin(), p_in.end(), out.begin(), boost::bind(boost::mem_fn(
                                       static_cast<char (std::ctype<wchar_t>::*)(wchar_t, char) const>(&std::ctype<wchar_t>::narrow)
                                                                                                                 ),
                                                                                                    &ctypeFacet, _1, def));
                                  return out;
                                 }
                                 catch(...)
                                 {
                                  return std::string();
                                 }        
                                };
                                Цитата Masterkent @
                                Цитата Alca @
                                Преобразование std::string в std::wstring туда и обратно, как делается?

                                Стандартными средствами C++ примерно так можно:

                                ExpandedWrap disabled
                                  #include <iostream>
                                  #include <locale>
                                  #include <string>
                                  #include <vector>
                                   
                                  std::wstring wide_string(std::string const &s, std::locale const &loc)
                                  {
                                      if (s.empty())
                                          return std::wstring();
                                      std::ctype<wchar_t> const &facet = std::use_facet<std::ctype<wchar_t> >(loc);
                                      char const *first = s.c_str();
                                      char const *last = first + s.size();
                                      std::vector<wchar_t> result(s.size());
                                      
                                      facet.widen(first, last, &result[0]);
                                      
                                      return std::wstring(result.begin(), result.end());
                                  }
                                   
                                  std::string narrow_string(std::wstring const &s, std::locale const &loc, char default_char = '?')
                                  {
                                      if (s.empty())
                                          return std::string();
                                      std::ctype<wchar_t> const &facet = std::use_facet<std::ctype<wchar_t> >(loc);
                                      wchar_t const *first = s.c_str();
                                      wchar_t const *last = first + s.size();
                                      std::vector<char> result(s.size());
                                      
                                      facet.narrow(first, last, default_char, &result[0]);
                                      
                                      return std::string(result.begin(), result.end());
                                  }
                                   
                                  char const *russian_locale_designator = "rus"; // обозначение локали зависит от реализации,
                                                                                 // "rus" подходит для VC++
                                   
                                  int main()
                                  {
                                      std::locale loc(russian_locale_designator);
                                   
                                      std::wstring const s  = L"русский текст";
                                      std::string const  sa = ::narrow_string(s, loc);
                                      std::wstring const sw = ::wide_string(sa, loc);
                                          
                                      std::locale::global(loc);
                                      
                                      std::wcout << "original  wide: " << s  << std::endl;
                                      std::cout  << "wide -> narrow: " << sa << std::endl;
                                      std::wcout << "narrow -> wide: " << sw << std::endl;
                                  }

                                Возникла необходимость преобразования wstring в string. Из упомянутых здесь способов этот больше всего приглянулся. Но подскажите пожалуйста почему при первом преобразовании он из строки "ddd" делает строку "?ddd"? Причем если делать два преобразования подряд, то во второй раз символ спереди не добавляется.
                                Я в крайнем случае могу его просто отбрасывать, но во-первых интересно знать причину, во-вторых это наводит на мысль - а не ждут ли меня еще какие сюрпризы?
                                (способ Киллера кстати тоже прибавляет символ спереди)

                                В этих строках у меня железно только цифры и латинские буквы, так что никакие проблемы с кодировками меня сейчас не интересуют, нужно просто самое элементарное преобразование.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0462 ]   [ 16 queries used ]   [ Generated: 15.09.25, 07:05 GMT ]