Re: Стандарт перевода wchar_t в char
От: K13 http://akvis.com
Дата: 09.02.10 08:03
Оценка: 3 (2) +1
думаю, лучше всего взять libiconv
Re: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 09.02.10 20:49
Оценка: 6 (2)
Здравствуйте, <Аноним>, Вы писали:

А>что на данный момент является стандартом С++ преобразования из wchar_t в char?


Пока только что только proposed wstring_convert

А>Например, вывести в поток ofstream строку wchar_t (не двоичным образом, а предврительным преобразованием в char).


Используя C, что входит в стандартную библиотеку C++:
int main()
{
  using namespace std;
  wstring ws = L"wide string";
  //setlocale(LC_ALL, "russian");
  ostream_iterator<char> osi(cout);
  transform(ws.begin(), ws.end(), osi, wctob);
}
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: Стандарт перевода wchar_t в char
От: A_P  
Дата: 09.02.10 13:06
Оценка: 1 (1) +1
Какая OS, какой компилятор?
Какие библиотеки, сказали использовать?

Win API функции:
MultiByteToWideChar
WideCharToMultiByte

Большинство функций, макросов, классов — это обертки вокруг этих двух функций, если вы под Windows
Re[6]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 11.02.10 08:32
Оценка: :))
Здравствуйте, Mr.Cat, Вы писали:

MC>Здравствуйте, fk0, Вы писали:

fk0>>у GCC представление о кодировке "строки" и L"строки" в корне принципиально разное. Первая никак не перекодируется при чтении файла (почему бы не взять кодировку из локали?)
MC>Ага, и при компиляции на машинах с разными локалями будет получаться разный код.

Вот я и говорю, этот ваш GCC -- жалкая поделка финских студентов...
Re: Стандарт перевода wchar_t в char
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 11.02.10 08:47
Оценка: 2 (1)
Здравствуйте, Аноним, Вы писали:

А>Подскажите, гуру, что на данный момент является стандартом С++ преобразования из wchar_t в char?

А>Нарыл вагон примеров. Все работает, но мне надо для тестового задания точно знать, как ПРАВИЛЬНО и переносимо сделать преобразование.
А>Например, вывести в поток ofstream строку wchar_t (не двоичным образом, а предврительным преобразованием в char).
А>Заранее спасибо.

Уже не помню где, я находил следующий вариант преобразования:


struct widen : std::unary_function<char, wchar_t>
{
   widen(const std::ctype<wchar_t> &ct)
      : charType(ct)
   {}
   wchar_t operator()(char c)
   {
      return charType.widen(c);
   }
private:
   const std::ctype<wchar_t> &charType;
};

struct narrow : std::unary_function<wchar_t, char>
{
   narrow(const std::ctype<wchar_t> &ct)
      : charType(ct)
   {}
   char operator()(wchar_t c)
   {
      return charType.narrow(c);
   }
private:
   const std::ctype<wchar_t> &charType;
};
inline std::wstring to_wstring(const std::string &s, const std::locale &curLocale = std::locale::classic())
{
   std::wstring retVal;
   widen w(std::use_facet<std::ctype<wchar_t> >(curLocale));
   std::transform(s.begin(), s.end(), std::back_inserter(retVal), w);
   return retVal;
}

inline std::string to_string(const std::wstring &s, const std::locale &curLocale = std::locale::classic())
{
   std::string retVal;
   narrow n(std::use_facet<std::ctype<wchar_t> >(curLocale));
   std::transform(s.begin(), s.end(), std::back_inserter(retVal), n);
   return retVal;
}



Это может быть и переносимый вариант, но железно тормозной. По сравнению с использованием макросов ATL, этот вариант медленнее на порядок.
Re[4]: Стандарт перевода wchar_t в char
От: Mr.Cat  
Дата: 10.02.10 15:44
Оценка: +1
Здравствуйте, gear nuke, Вы писали:
GN>Коневерсия выполняется (как просили "предврительным преобразованием в char") функуией wctob в соответствии с кодовой страницей выбраной для текущей локали
А если локаль — utf8?
Re[6]: Стандарт перевода wchar_t в char
От: Mr.Cat  
Дата: 11.02.10 00:09
Оценка: +1
Здравствуйте, gear nuke, Вы писали:
GN>Ровно как и wctob не будет конвертировать в более чем однобайтное представление.
Ну я на это и намекал.
Кстати, мне почему-то кажется, что с iconv будет проще, чем со всякими ортодоксатьными сиплюсплюсными потоками-шаблонами. Например, когда я последний раз интересовался, в бусте (в частности, xpressive) не было поддержки utf8 — и, мне кажется, это неспроста.
Re[5]: Стандарт перевода wchar_t в char
От: Mr.Cat  
Дата: 11.02.10 07:59
Оценка: +1
Здравствуйте, fk0, Вы писали:
fk0> Если на G* начинается -- однозначно поделка. Православно только ISO/IEC.
Ну тогда -- однозначно трололо.
Стандарт перевода wchar_t в char
От: Аноним  
Дата: 09.02.10 07:33
Оценка:
Подскажите, гуру, что на данный момент является стандартом С++ преобразования из wchar_t в char?
Нарыл вагон примеров. Все работает, но мне надо для тестового задания точно знать, как ПРАВИЛЬНО и переносимо сделать преобразование.
Например, вывести в поток ofstream строку wchar_t (не двоичным образом, а предврительным преобразованием в char).
Заранее спасибо.
Re[2]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 09.02.10 20:52
Оценка:
Здравствуйте, A_P, Вы писали:

A_P>Какая OS, какой компилятор?

A_P>Какие библиотеки, сказали использовать?

Написано же всё:

переносимо сделать преобразование

.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Стандарт перевода wchar_t в char
От: puredev  
Дата: 10.02.10 09:20
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, <Аноним>, Вы писали:


А>>что на данный момент является стандартом С++ преобразования из wchar_t в char?


GN>Пока только что только proposed wstring_convert


А>>Например, вывести в поток ofstream строку wchar_t (не двоичным образом, а предврительным преобразованием в char).


GN>Используя C, что входит в стандартную библиотеку C++:

GN>
GN>int main()
GN>{
GN>  using namespace std;
GN>  wstring ws = L"wide string";
GN>  //setlocale(LC_ALL, "russian");
GN>  ostream_iterator<char> osi(cout);
GN>  transform(ws.begin(), ws.end(), osi, wctob);
GN>}
GN>


Спасибо за пример! Единственно, мне надо было в файл (ofstream):

std::ofstream Logger::_file("task.log", std::ios::out|std::ios::trunc);

...
void Logger::trace(std::wstring& text) throw() {
_file << " ## " << std::endl;

setlocale(LC_ALL, "russian");
std::ostream_iterator<char> osi( _file );
transform( text.begin(), text.end(), osi, wctob );
}

надеюсь прокатит
Re[2]: Стандарт перевода wchar_t в char
От: alsemm Россия  
Дата: 10.02.10 09:40
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Используя C, что входит в стандартную библиотеку C++:

GN>
GN>int main()
GN>{
GN>  using namespace std;
GN>  wstring ws = L"wide string";
GN>  //setlocale(LC_ALL, "russian");
GN>  ostream_iterator<char> osi(cout);
GN>  transform(ws.begin(), ws.end(), osi, wctob);
GN>}
GN>

И в какой кодировке будет вывод в osi? win1251? koi8r? или utf8?
Re[3]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 10.02.10 15:38
Оценка:
Здравствуйте, alsemm, Вы писали:

A>И в какой кодировке будет вывод в osi? win1251? koi8r? или utf8?


Я не понял вопрос. Если выводить в файловый стрим, то ostream_iterator будет использовать
ofstream& operator<<(ofstream&, char);
который не выполняет коверсию.

Коневерсия выполняется (как просили "предврительным преобразованием в char") функуией wctob в соответствии с кодовой страницей выбраной для текущей локали

int main()
{
  using namespace std;
  wstring ws = L"wide строка.";
  //setlocale(LC_ALL, ".1251"); // хз как получить кодовую стариницу, потому альтернатива ниже
  locale::global(locale(".1251")); // кодировка для конверсии wctob
  cout << cout.getloc().name() << '\n';
  cout.imbue(locale()); // устанавливаем для стрима глобальную локаль, кодировка выбрана выше
  cout << cout.getloc().name() << '\n';
  cout.imbue(locale(".1252")); // не влияет на конверсию
  cout << cout.getloc().name() << '\n';
  ostream_iterator<char> osi(cout);
  transform(ws.begin(), ws.end(), osi, wctob);
}


C
Russian_Russia.1251
Russian_Russia.1252
wide строка.

Поскольку в моём примере osi выводит на консоль, то она будет отображать используя локаль пользователя по умолчанию.

Или намекалось, что следует для конверсии использовать фасеты? Тогда на вопрос "как ПРАВИЛЬНО?" я скажу что надо читать документацию, что бы не напутать.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Стандарт перевода wchar_t в char
От: alsemm Россия  
Дата: 10.02.10 20:01
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Или намекалось, что следует для конверсии использовать фасеты?

Нет, не намекалось. Просто в исходном примере
setlocale(LC_ALL, "russian");

было не понятно, как указывается кодировка.

В любом случае, толку от wctob никакого, если в локали выбрана кодировка utf8, как заметил Mr.Cat
Re[5]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 10.02.10 23:07
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>А если локаль — utf8?


Значит настало будущее, 0x год

Локаль несклько шире, чем кодовая страница, это набор фасетов. Кодовые страницы относятся к фасетам категории ctype. Текущий стандарт определяет 2 фасета, из которых конверсию выполняет только один — codecvt<wchar_t,char,mbstate_t>. Кодировки, для которых выполняется конверсия, зависят от реализации. В частности MSVC не поддерживает кодовые страницы utf-7 & utf-8. Ровно как и wctob не будет конвертировать в более чем однобайтное представление.

Если пройти по ссылке (из первого ответа) на proposal, то можно увидеть:

Say, for example, you have a code conversion facet called codecvt_utf8 that you want to use to output to cout a UTF-8 multibyte sequence corresponding to a wide string

то есть предполагается, что его надо где-то взять (с инструкциями к использованию).

Так же по той ссылке сказано:

Note that the Standard C++ library currently uses code conversion facets only within template class basic_filebuf, for converting from multibyte sequences when reading from a file and for converting to multibyte sequences when writing to a file

что намекает, что конверсия может выполняеться непосредственно при выводе в файл (но, как я понял вопрос, это не интересовало).

И, кстати, в исходном вопросе ничего про кодировки не сказано, о чём я намекал закомментированной строкой
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 10.02.10 23:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Подскажите, гуру, что на данный момент является стандартом С++ преобразования из wchar_t в char?


Про C++ не скажу. Там может что-то поверх C-шных интерфейсов быть. Не знаю.

Если вообще, то примерно это: http://www.unix.org/version2/whatsnew/mse.html

А>Нарыл вагон примеров. Все работает, но мне надо для тестового задания точно знать, как ПРАВИЛЬНО и переносимо сделать преобразование.


Вы таки определитесь, вам по стандарту (ISO, ГОСТ, IEEE, etc...) или под windows.

А>Например, вывести в поток ofstream строку wchar_t (не двоичным образом, а предврительным преобразованием в char).


mbstowcs(wchar_t*,...)
Re[2]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 10.02.10 23:33
Оценка:
Здравствуйте, K13, Вы писали:

K13>думаю, лучше всего взять libiconv


Если он не интегрирован в libc штатно -- оно не более чем жалкая поделка финских студентов.
Re[3]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 10.02.10 23:35
Оценка:
Здравствуйте, alsemm, Вы писали:

A>И в какой кодировке будет вывод в osi? win1251? koi8r? или utf8?


В зависимой от локали. В теории...
Re[3]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 10.02.10 23:37
Оценка:
Здравствуйте, puredev, Вы писали:

А>>>что на данный момент является стандартом С++ преобразования из wchar_t в char?


GN>> ostream_iterator<char> osi(cout);

GN>> transform(ws.begin(), ws.end(), osi, wctob);

DESCRIPTION
The wctob() function tests whether the multi-byte representation of the
wide character c, starting in the initial state, consists of a single
byte. If so, it is returned as an unsigned char.

Never use this function. It cannot help you in writing international-
ized programs. Internationalized programs must never distinguish sin-
gle-byte and multi-byte characters.

Читайте маны, они рулез (C)

P>надеюсь прокатит


Нипракатило. mbstowcs таки прокатит. Но я бы потестировал везде, вроде как нигде кроме линуха
оно толком не работает вроде как.
Re[3]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 10.02.10 23:41
Оценка:
Здравствуйте, puredev, Вы писали:

P>Спасибо за пример!

P>Единственно, мне надо было в файл (ofstream):

А я может быть и не понял вопрос Пример был "с предврительным преобразованием в char".
Такой вариант известен?
  wfstream wf("log", std::ios::out|std::ios::trunc);
  wf << L"ddd";
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 10.02.10 23:55
Оценка:
Здравствуйте, gear nuke, Вы писали:

А>>что на данный момент является стандартом С++ преобразования из wchar_t в char?


GN>Используя C, что входит в стандартную библиотеку C++:

GN>
GN>int main()
GN>{
GN>  using namespace std;
GN>  wstring ws = L"wide string";
GN>  //setlocale(LC_ALL, "russian");
GN>  ostream_iterator<char> osi(cout);
GN>  transform(ws.begin(), ws.end(), osi, wctob);
GN>}
GN>


Говнокод.

#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
#include <wchar.h>

int main()
{
const wchar_t *str = L"Превед мир.";
char buf[256];
int i;
    setlocale(LC_ALL, "");

    i=wcstombs(buf, str, sizeof(buf));
    if (i<0) {
        printf("wcstombs: can't convert in current locale.\n");
    } else {
        printf("wcstombs: %s\n", buf);
    }

    fputs("wctomb: ", stdout);
    while (*str) {
        i=wctob(*str++);
        if (i>0) putchar(i);
    }
    putchar('\n');
    
    return 0;
}

$ gcc -Wall test.c
$ locale |grep LC_CTYPE
LC_CTYPE=ru_RU.KOI8-R
$ ./a.out 
wcstombs: Перевед мир.
wctomb: Перевед мир.
$ LC_ALL=ru_RU.UTF-8 ./a.out | iconv -f utf8
wcstombs: Перевед мир.
wctomb:  .


В последней строке сущность говнокода проявлена.

С другой стороны, повторюсь, мне проверить сейчас негде, но я чуть менее чем уверен, что на разных вариантах BSD и Solaris будет хрен в 8-битных локалях. Возможно. В линуксе всё чотка. Что будет в виндах не знаю, но скорей вообще работать не будет, только если в cygwin, поэтому если говорить о переносимости, то скорей либо писать свои обёртки под разные платформы, либо пытаться реализовать для отдельных ущербных платформ собственные функции поддержки конверсии wchar_t как должно быть по стандарту.
Re[4]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 10.02.10 23:59
Оценка:
Здравствуйте, fk0, Вы писали:

fk0>DESCRIPTION

fk0> The wctob() function tests whether the multi-byte representation of the
fk0> wide character c, starting in the initial state, consists of a single
fk0> byte. If so, it is returned as an unsigned char.

fk0> Never use this function. It cannot help you in writing international-

fk0> ized programs. Internationalized programs must never distinguish sin-
fk0> gle-byte and multi-byte characters.

fk0> Читайте маны, они рулез (C)


rule — значит правило, стандарт. А маны привирают про возвращаемое значение. Нужна ли конверсия из wchar_t в char в "internationalized programs", или где-то ещё — с какой стати маны решают за пользователя, это так называемая свобода?

Description
The wctob function determines whether c corresponds to a member of the extended
character set whose multibyte character representation is a single byte when in the initial
shift state.

Returns
The wctob returns EOF if c does not correspond to a multibyte character with length
one in the initial shift state. Otherwise, it returns the single-byte representation of that
character as an unsigned char converted to an int.


fk0>mbstowcs таки прокатит. Но я бы потестировал везде, вроде как нигде кроме линуха

fk0>оно толком не работает вроде как.

mbstowcs определена в стандарте С, при чём тут линух
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[5]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 11.02.10 00:05
Оценка:
Здравствуйте, gear nuke, Вы писали:

fk0>>DESCRIPTION

fk0>> The wctob() function tests whether the multi-byte representation of the
fk0>> wide character c, starting in the initial state, consists of a single
fk0>> byte. If so, it is returned as an unsigned char.

fk0>> Never use this function. It cannot help you in writing international-

fk0>> ized programs. Internationalized programs must never distinguish sin-
fk0>> gle-byte and multi-byte characters.

fk0>> Читайте маны, они рулез (C)

GN>rule — значит правило, стандарт. А маны привирают про возвращаемое значение. Нужна ли конверсия из wchar_t в char в "internationalized programs", или где-то ещё — с какой стати маны решают за пользователя, это так называемая свобода?

Свобода -- это рабство. (C)

Маны какбе подсказывают и уберегают от говнокода. Жителям свободной страны конечно наплевать на internationalized characters, но неизвестно кто будет пользоваться их (говно)софтом.

fk0>>mbstowcs таки прокатит. Но я бы потестировал везде, вроде как нигде кроме линуха

fk0>>оно толком не работает вроде как.
GN>mbstowcs определена в стандарте С, при чём тут линух

Вообще я имел ввиду wcstombs. Линух при том, что только в егойной гнутой libc более-менее это всё работает. Мне и самому интересно знать где и как не работает. У freebsd или openbsd своя libc, у солярисов своя, у микрософта вообще чёрт ногу сломит. А "стандарту" не так уж много лет. И даже в линухе это может не работать в некоторых случаях (например, при несгенерированной локали, как я понимаю, фиг что будет).
Re[3]: Стандарт перевода wchar_t в char
От: Mr.Cat  
Дата: 11.02.10 00:34
Оценка:
Здравствуйте, fk0, Вы писали:
fk0> Если он не интегрирован в libc штатно -- оно не более чем жалкая поделка финских студентов.
В glibc, по идее, есть. А вообще трололо.
Re[3]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 11.02.10 01:08
Оценка:
Здравствуйте, fk0, Вы писали:

GN>>Используя C, что входит в стандартную библиотеку C++:

GN>>
GN>>int main()
GN>>{
GN>>  using namespace std;
GN>>  wstring ws = L"wide string";
GN>>  //setlocale(LC_ALL, "russian");
GN>>  ostream_iterator<char> osi(cout);
GN>>  transform(ws.begin(), ws.end(), osi, wctob);
GN>>}
GN>>


fk0> Говнокод.


Дык, сломай его.

fk0>$ gcc -Wall test.c

fk0>$ locale |grep LC_CTYPE
fk0>LC_CTYPE=ru_RU.KOI8-R
fk0>$ ./a.out
fk0>wcstombs: Перевед мир.
fk0>wctomb: Перевед мир.
fk0>$ LC_ALL=ru_RU.UTF-8 ./a.out | iconv -f utf8
fk0>wcstombs: Перевед мир.
fk0>wctomb: .
fk0>[/c]

fk0> В последней строке сущность говнокода проявлена.


То есть подменил строку для конверсии, установил вместо однобайтной локали мультибайтную и таким образом доказал? что многобайтный символ нельзя привести в 1 char

Можно еще с таким поэксперементировать
int main()
{
  setlocale(LC_ALL, "");
  wprintf(L"Перевед мир.");
  printf("Перевед мир.");
}
MSVC такое нормально переварит кстати, без шаманств с -finput-charset и converting to execution character set: Illegal byte sequence. Однако не буду применять слово "говнокомпилер" к GCC, скажу что у меня руки не оттуда растут
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[7]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 11.02.10 01:08
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

GN>>Ровно как и wctob не будет конвертировать в более чем однобайтное представление.

MC>Ну я на это и намекал.

Ээ... это только я понял, что под "преобразованием в char" подразумевается не "в последовательность char"?

MC>Кстати, мне почему-то кажется, что с iconv будет проще, чем со всякими ортодоксатьными сиплюсплюсными потоками-шаблонами.


Может быть даже не проще, а лучше, но это не Стандарт. utf-8 появится только в новом Стандарте, отсюда, наверное и отсутствие его в "в бусте (в частности, xpressive)".
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[6]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 11.02.10 02:38
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Свобода -- это рабство. (C)


"хлеба и зрелищь"?

fk0> Маны какбе подсказывают и уберегают от говнокода.


Не заметно. Посмотри внимательно: в твоем коде
Автор: fk0
Дата: 11.02.10
потенциальное переполнение буфера.

fk0> Жителям свободной страны конечно наплевать на internationalized characters, но неизвестно кто будет пользоваться их (говно)софтом.


Открою секрет: не-православная-ОС нативно поддерживает эти самые "internationalized characters", поэтому мне и в голову не придёт хранить что то такое в char[] и заниматься конверсиями из пустого в порожнее, без особых на то причин.

fk0>И даже в линухе это может не работать в некоторых случаях (например, при несгенерированной локали, как я понимаю, фиг что будет).


То есть отвергнув одно, ты осознанно предложил полурешение
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 11.02.10 02:53
Оценка:
Здравствуйте, gear nuke, Вы писали:

fk0>>$ LC_ALL=ru_RU.UTF-8 ./a.out | iconv -f utf8

fk0>>wcstombs: Перевед мир.
fk0>>wctomb: .
fk0>>[/c]
fk0>> В последней строке сущность говнокода проявлена.
GN>То есть подменил строку для конверсии, установил вместо однобайтной локали мультибайтную и таким образом доказал? что многобайтный символ нельзя привести в 1 char

Я дурацких ухмылок не понимаю.

Да, нельзя. Албанский работать перестанет.

GN>
GN>int main()
GN>{
GN>  setlocale(LC_ALL, "");
GN>  wprintf(L"Перевед мир.");
GN>  printf("Перевед мир.");
GN>}
GN>


GN>MSVC такое нормально переварит кстати,


Нормально -- это ортогонально к результату выдаваемому GCC?

Непонятно куда wprintf делаться будет, ибо там то место куда обязано поддерживать вывод wchar, а stdout в общем не поддерживает. Байт-ориентированный он. Как в него, спрашивается, 32-битные буквы записывать.

Пока писал абзац выше -- проверил. Таки выводит и в соответствии с локалью всё конвертирует. glibc 2.7. Пару лет назад где-то, на debian sarge или etch были проблемы и wprintf в файл фактически не работал. Возможно это как-то связано с fwide(), не скажу. Повторюсь, работает всё только в модных новых линухах, у остальных разброд и шатания.
И кстати применение wprintf ломает работу байт-ориентированных фуннкций вроде printf (просто не выводится). Не всё тут так хорошо...

GN> без шаманств с -finput-charset и converting to execution character set: Illegal byte sequence.


Опенсоурс так старался быть похожим на виндовс, так старался догнать микрософт, и в этой части, кажется, уже преуспел в этом: у GCC представление о кодировке "строки" и L"строки" в корне принципиально разное. Первая никак не перекодируется при чтении файла (почему бы не взять кодировку из локали?), вторая ожидается именно UTF-8. Микрософт в windows и outlook тоже использует 4 разных кодировки для русского языка...

Резюме такое: исходники держать только в UTF-8 (локаль при этом не мешает иметь KOI8, хотя местами может быть проблемно...) Оно, кстати, справедливо, ибо наткнуться на кодировку ещё можно в CVS/SVN и ещё десятке мест. И с юникодом все худо-бедно работают, а с перекодировками туда-сюда вряд ли.

GN> Однако не буду применять слово "говнокомпилер" к GCC, скажу что у меня руки не оттуда растут


В этом месте -- таки да. Но, см. выше. В этом даже есть позитив: что, спрашивается, ты будешь делать с KOI8 строками в исходнике и далее в бинарнике? Их на вывод перекодировать вот так просто -- никак, при чём KOI8 локаль может быть не сгенерирована попросту -- тогда вообще никак. С UTF-8 несколько веселее, потому что, по-дефолту UTF-8 локаль обычно есть и как я понимаю, в любой подходящей локали текст в итоге можно выдать путём двойного преобразования... в виду чего лучше таки использовать wchar... В общем нет места надписям на русском языке, в 8-битной кодировке, в исходнике.
Re[7]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 11.02.10 03:00
Оценка:
Здравствуйте, gear nuke, Вы писали:

fk0>> Маны какбе подсказывают и уберегают от говнокода.

GN>Не заметно. Посмотри внимательно: в твоем коде
Автор: fk0
Дата: 11.02.10
потенциальное переполнение буфера.


Мой код писался какбе для демонстрации (не)работы wcstomb, а не как академический пример правильного программирования.

fk0>> Жителям свободной страны конечно наплевать на internationalized characters, но неизвестно кто будет пользоваться их (говно)софтом.

GN>Открою секрет: не-православная-ОС нативно поддерживает эти самые "internationalized characters", поэтому мне и в голову не придёт хранить что то такое в char[] и заниматься конверсиями из пустого в порожнее, без особых на то причин.

В итоге они вообще не используют библиотеку C и задают здесь вопрос как сконвертить. Ага. И все функции там _A и _W на всякий случай. При чём из файла они всё равно читают _A и вынуждены как-то сконвертить. Этот секрет хорошо звучит только в маркетинге, до тех пор пока никто не знает как же оно там внутри устроено.

fk0>>И даже в линухе это может не работать в некоторых случаях (например, при несгенерированной локали, как я понимаю, фиг что будет).

GN>То есть отвергнув одно, ты осознанно предложил полурешение

Ты вообще не решение предложил. В смысле не работающее для русского языка.
Re[7]: о говнокодах
От: fk0 Россия https://fk0.name
Дата: 11.02.10 03:05
Оценка:
Здравствуйте, gear nuke, Вы писали:

fk0>> Маны какбе подсказывают и уберегают от говнокода.

GN>Не заметно. Посмотри внимательно: в твоем коде
Автор: fk0
Дата: 11.02.10
потенциальное переполнение буфера.


Кстати ложь и провокация. Там есть не потенциальное, а практическое отсутствие терминирующего нуля (printf(buf)).
Re[4]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 11.02.10 03:06
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Здравствуйте, fk0, Вы писали:

fk0>> Если он не интегрирован в libc штатно -- оно не более чем жалкая поделка финских студентов.
MC>В glibc, по идее, есть. А вообще трололо.

Если на G* начинается -- однозначно поделка. Православно только ISO/IEC.
Re[5]: Стандарт перевода wchar_t в char
От: Mr.Cat  
Дата: 11.02.10 08:08
Оценка:
Здравствуйте, fk0, Вы писали:
fk0>у GCC представление о кодировке "строки" и L"строки" в корне принципиально разное. Первая никак не перекодируется при чтении файла (почему бы не взять кодировку из локали?)
Ага, и при компиляции на машинах с разными локалями будет получаться разный код.
Re[7]: Стандарт перевода wchar_t в char
От: LuciferSaratov Россия  
Дата: 11.02.10 09:24
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Вот я и говорю, этот ваш GCC -- жалкая поделка финских студентов...


Уже третий заход, а еды все нет.
Re[5]: Стандарт перевода wchar_t в char
От: gear nuke  
Дата: 11.02.10 21:52
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Я дурацких ухмылок не понимаю.


fk0> Да, нельзя. Албанский работать перестанет.


Вот для этого случая я не стал искать подходящие условия, как это сделал ты.
    if (i<0) {
        printf("wcstombs: can't convert in current locale.\n");

Обрати внимание на эту подветку
Автор: alsemm
Дата: 10.02.10
где люди более толково донесли твою мысль

fk0> Пока писал абзац выше -- проверил. Таки выводит и в соответствии с локалью всё конвертирует.


Так и должно быть по стандарту происходит конверсия при выводе в стрим. Неужели в манах про это нет?

fk0>glibc 2.7. Пару лет назад где-то, на debian sarge или etch были проблемы и wprintf в файл фактически не работал. Возможно это как-то связано с fwide(), не скажу. Повторюсь, работает всё только в модных новых линухах, у остальных разброд и шатания.


В них C runtime реализован не полно.

fk0> И кстати применение wprintf ломает работу байт-ориентированных фуннкций вроде printf (просто не выводится). Не всё тут так хорошо...


Потому что стримы имеют оринтацию, т.н. byte-oriented и wide-oriented, устанавливается в зависимости от типа первой функции делающей ввод-вывод.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[8]: о говнокодах
От: gear nuke  
Дата: 11.02.10 21:52
Оценка:
Здравствуйте, fk0, Вы писали:

GN>>Посмотри внимательно: в твоем коде
Автор: fk0
Дата: 11.02.10
потенциальное переполнение буфера.


fk0> Кстати ложь и провокация. Там есть не потенциальное, а практическое отсутствие терминирующего нуля (printf(buf)).


Ну '\0' то иногда будет дописываться

The wcstombs function converts a sequence of wide characters from the array pointed
to by pwcs into a sequence of corresponding multibyte characters that begins in the
initial shift state, and stores these multibyte characters into the array pointed to by s,
stopping if a multibyte character would exceed the limit of n total bytes or if a null
character is stored
.

.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Стандарт перевода wchar_t в char
От: skeptik_  
Дата: 12.02.10 01:48
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Здравствуйте, Аноним, Вы писали:


А>>Подскажите, гуру, что на данный момент является стандартом С++ преобразования из wchar_t в char?

А>>Нарыл вагон примеров. Все работает, но мне надо для тестового задания точно знать, как ПРАВИЛЬНО и переносимо сделать преобразование.
А>>Например, вывести в поток ofstream строку wchar_t (не двоичным образом, а предврительным преобразованием в char).
А>>Заранее спасибо.

ST>Уже не помню где, я находил следующий вариант преобразования:


http://rsdn.ru/forum/cpp.applied/3090740.1.aspx
Автор: skeptik_
Дата: 05.09.08
Re[2]: Стандарт перевода wchar_t в char
От: MescalitoPeyot Украина  
Дата: 12.02.10 06:04
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Уже не помню где, я находил следующий вариант преобразования:

Имхо лучше такой способ не использовать, по крайней мере в направлении wchar_t -> char из-за проблемы с мультибайтностью
... << RSDN@Home 1.2.0 alpha 4 rev. 1138>>
Re[6]: Стандарт перевода wchar_t в char
От: MasterZiv СССР  
Дата: 12.02.10 09:06
Оценка:
fk0 wrote:

> Вообще я имел ввиду wcstombs. Линух при том, что только в егойной гнутой

> libc более-менее это всё работает. Мне и самому интересно знать где и
> как не работает.

Ну вроде под виндой в VC работает нормально.
Posted via RSDN NNTP Server 2.1 beta
Re[9]: о говнокодах
От: fk0 Россия https://fk0.name
Дата: 13.02.10 18:49
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>>>Посмотри внимательно: в твоем коде
Автор: fk0
Дата: 11.02.10
потенциальное переполнение буфера.

fk0>> Кстати ложь и провокация. Там есть не потенциальное, а практическое отсутствие терминирующего нуля (printf(buf)).
GN>Ну '\0' то иногда будет дописываться
GN>

The wcstombs function converts a sequence of wide characters from the array pointed
GN>to by pwcs into a sequence of corresponding multibyte characters that begins in the
GN>initial shift state, and stores these multibyte characters into the array pointed to by s,
GN>stopping if a multibyte character would exceed the limit of n total bytes or if a null
GN>character is stored
.


То-есть никакого переполнения нет.
Re[6]: Стандарт перевода wchar_t в char
От: fk0 Россия https://fk0.name
Дата: 13.02.10 18:52
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Вот для этого случая я не стал искать подходящие условия, как это сделал ты.

GN>
GN>    if (i<0) {
GN>        printf("wcstombs: can't convert in current locale.\n");
GN>

GN>Обрати внимание на эту подветку
Автор: alsemm
Дата: 10.02.10
где люди более толково донесли твою мысль


Ниасилел. В текущей локали.

fk0>> Пока писал абзац выше -- проверил. Таки выводит и в соответствии с локалью всё конвертирует.


Дадада.

GN>Так и должно быть по стандарту происходит конверсия при выводе в стрим. Неужели в манах про это нет?


Ойойой! Не факт. Не путать C++ и libc (без ++).

fk0>>glibc 2.7. Пару лет назад где-то, на debian sarge или etch были проблемы и wprintf в файл фактически не работал. Возможно это как-то связано с fwide(), не скажу. Повторюсь, работает всё только в модных новых линухах, у остальных разброд и шатания.

GN>В них C runtime реализован не полно.

Да хоть как. Сам факт -- не работает!

fk0>> И кстати применение wprintf ломает работу байт-ориентированных фуннкций вроде printf (просто не выводится). Не всё тут так хорошо...

GN>Потому что стримы имеют оринтацию, т.н. byte-oriented и wide-oriented, устанавливается в зависимости от типа первой функции делающей ввод-вывод.

Только fwide чо-та не памагаит. Я б поастерёгса использовать такие функции.
Re[5]: Стандарт перевода wchar_t в char
От: Tujh Голландия  
Дата: 16.02.10 19:28
Оценка:
Здравствуйте, fk0, Вы писали:
fk0> И кстати применение wprintf ломает работу байт-ориентированных фуннкций вроде printf (просто не выводится). Не всё тут так хорошо...
Глупость, ни чего не ломается, нужно просто "доработать напильником"

    // set C/C++ locale
    cout << "set system console locale..." 
         << endl
         << "C locale: "
         << setlocale(LC_ALL, "")
         << endl;
    locale::global(locale(""));
    cout << "C++ locale: "
         << locale().name().c_str()
         << endl
         << endl;
    //--------------------------------------------------------------------------
    // set C++ stream locale
    cout.imbue(locale());
    clog.imbue(locale());
    cerr.imbue(locale());
    wcout.imbue(locale());
    wclog.imbue(locale());
    wcerr.imbue(locale());
    //--------------------------------------------------------------------------
    // don't sync. c and c++ streams
    ios::sync_with_stdio(false);
    //--------------------------------------------------------------------------

После этих "шаманств" вывод в консоль и char-строк и wchar_t-строк проблем не вызовет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.