Re[11]: тысяча третий раз про Юникод
От: Sergey Россия  
Дата: 15.10.09 12:49
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>И что, внутри фасцета я могу рекурсивно вызвать повторное чтение, чтобы считать дополнительный байт и уложить его во вторую половину wchar_t?


Если говорить про ввод, то используется вот такая функция:

virtual result do_in(
     StateType& _State,
      const Byte* _First1, 
       const Byte* _Last1, 
     const Byte*& _Next1,
      CharType* _First2,
       CharType* _Last2,
      CharType*& _Next2,
) const;




_State
The conversion state that is maintained between calls to the member function.

_First1
Pointer to the beginning of the sequence to be converted.

_Last1
Pointer to the end of the sequence to be converted.

_Next1
Pointer beyond the end of the converted sequence, to the first unconverted character.

_First2
Pointer to the beginning of the converted sequence.

_Last2
Pointer to the end of the converted sequence.

_Next2
Pointer to the CharType that comes after the last converted CharType, to the first unaltered character in the destination sequence.


Return Value
A return that indicates the success, partial success, or failure of the operation. The function returns:

codecvt_base::error if the source sequence is ill formed.
codecvt_base::noconv if the function performs no conversion.
codecvt_base::ok if the conversion succeeds.
codecvt_base::partial if the source is insufficient or if the destination is not large enough, for the conversion to succeed.


Так что 8 и 16 битными байтами дело не ограничивается.

codecvt Class
A template class that describes an object that can serve as a locale facet that is able to control conversions between a sequence of values used to encode characters within the program and a sequence of values used to encode characters outside the program.


Понадобится — можно хоть из 24-битных CharType в 40-битные "байты" и наоборот конвертировать.
А че тут Rakafon про строго 8-битные байты наговорил, забудь.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[11]: тысяча третий раз про Юникод
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 15.10.09 13:07
Оценка:
Здравствуйте, pepsicoca, Вы писали:
P>И что, внутри фасцета я могу рекурсивно вызвать повторное чтение, чтобы считать дополнительный байт и уложить его во вторую половину wchar_t?

Да я просто говорю как стандартные потоковые классы себя ведут по умолчанию. Ничто вам не мешает написать свой фацет (наподобие, как здесь: Standard file streams and std::locale) и в функции do_in читать сразу 2 байта и помещать их соответственно в wchar_t, так же и наоборот в функции do_out из своей переменной wchar_t ложить в поток сразу два байта. Таким макаром можно хоть 16-ти байтовые символы иметь и читать и писать их за раз потоковым классом std::basic_ifstream<uint128>/std::basic_ofstream<uint128>. Просто для этого надо немного "ручками" изменить стандартное поведение потоковых классов.
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[12]: тысяча третий раз про Юникод
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 15.10.09 13:10
Оценка:
Здравствуйте, Sergey, Вы писали:
S>Понадобится — можно хоть из 24-битных CharType в 40-битные "байты" и наоборот конвертировать.
S>А че тут Rakafon про строго 8-битные байты наговорил, забудь.

Ха. Очень умно! Я говорю о стандартном поведении стандартных потоковых классов С++, а не о потоковых классах, обработанных напильником. Вот когда прилетят пришельцы, и вы получите таск заразить их бортовой писюк, в котором крутятся 40-битные байты, вируснёй, вот тогда и будете из 24-битных CharType в 40-битные "байты" и наоборот конвертировать.
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[5]: тысяча третий раз про Юникод
От: alsemm Россия  
Дата: 15.10.09 13:33
Оценка:
Здравствуйте, pepsicoca, Вы писали:

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


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


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


P>>>>>3. Если в экзешнике уже лежит Юникодная строка, почему кириллица не печатается без явного указания локали функцией imbue? Ведь по Юникоду однозначно определяется начертание символа. И чтобы напечатать Юникод локаль не нужна.


K13>>>>потоки ввода-вывода работают с char. Без указания, какая именно кодировка является активной, не обойтись.


P>>>Эта информация содержится в каждом коде Юникода. То есть по коду Юникода можно понять, какой это язык и слазить в систему за соответствующим начертанием символа в соответствующую таблицу.

A>>Что это за таблица такая волшебная?

P>Ну где там винда хранит начертание символов? В шрифтах наверное. Значит в шрифт.

Ну и что ей делать, если в шрифте который выбран для консоли нет глифа соответ. юникодному символу?
Re[6]: тысяча третий раз про Юникод
От: pepsicoca  
Дата: 15.10.09 14:00
Оценка:
Здравствуйте, alsemm, Вы писали:

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


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


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


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


P>>>>>>3. Если в экзешнике уже лежит Юникодная строка, почему кириллица не печатается без явного указания локали функцией imbue? Ведь по Юникоду однозначно определяется начертание символа. И чтобы напечатать Юникод локаль не нужна.


K13>>>>>потоки ввода-вывода работают с char. Без указания, какая именно кодировка является активной, не обойтись.


P>>>>Эта информация содержится в каждом коде Юникода. То есть по коду Юникода можно понять, какой это язык и слазить в систему за соответствующим начертанием символа в соответствующую таблицу.

A>>>Что это за таблица такая волшебная?

P>>Ну где там винда хранит начертание символов? В шрифтах наверное. Значит в шрифт.

A>Ну и что ей делать, если в шрифте который выбран для консоли нет глифа соответ. юникодному символу?

На выбор:

1. Ругнуться (вернуть ошибку потока).
2. Поискать в другом шрифте.
3. Пожаловаться в ЛСР.
4. Предложить сменить шрифт консоли.
5. Сменить шрифт консоли автоматически.
6. Иметь шрифт консоли со всеми символами Юникода (не зря же винда занимает свои гигабайты на диске).
7. Вывести знак вопроса на месте символа.

Впрочем, все это не имеет отношения к обсуждаемому вопросу. Такие же проблемы со шрифтом возникают, если я сам подключаю локаль с помощью imbue (то есть вполне может не быть нужного шрифта в системе). Я только хочу, чтобы для широких потоков imbue делалось автоматически. Вся информация для того, чтобы по коду Юникодного символа определять кодировку в системе есть. Зачем для этого напрягать пользователя — непонятно.
Re[13]: тысяча третий раз про Юникод
От: Sergey Россия  
Дата: 15.10.09 14:01
Оценка:
Здравствуйте, Rakafon, Вы писали:

S>>Понадобится — можно хоть из 24-битных CharType в 40-битные "байты" и наоборот конвертировать.

S>>А че тут Rakafon про строго 8-битные байты наговорил, забудь.

R>Ха. Очень умно! Я говорю о стандартном поведении стандартных потоковых классов С++, а не о потоковых классах, обработанных напильником.


Стандарт ничего не говорит о том, что конверсию из последовательности wchar_t в последовательность char надо делать так, будто с широкого конца у нас UTF-16 а с узкого — cp1251 или че там у юзера в винде задано. Лично я обычно предпочитаю такую конверсию, при которой половинки (или там четвертинки) wchar_t раскладываются по байтам тупо по порядку Как не трудно догадаться, при этом особой разницы между разными размерами "байт" в файлах нет.
Ну и вызов imbue за доработку напильником я тоже не считаю.

R>Вот когда прилетят пришельцы, и вы получите таск заразить их бортовой писюк, в котором крутятся 40-битные байты, вируснёй, вот тогда и будете из 24-битных CharType в 40-битные "байты" и наоборот конвертировать.


Все ж знают — у пришельцев система счисления с основанием e, а вовсе не двоичная. Так что С++ тут не годицца.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[7]: тысяча третий раз про Юникод
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 15.10.09 14:46
Оценка: -1
Здравствуйте, pepsicoca, Вы писали:
P>Я только хочу, чтобы для широких потоков imbue делалось автоматически. Вся информация для того, чтобы по коду Юникодного символа определять кодировку в системе есть.

Я как-то раз ехал домой с работы в маршрутке, и рядом сел молодой папаша с маленьким сыном в возрасте "почемучки". У них среди прочего состоялся такой разговор.

— Папа, а почему трамваи ездят по рельсам, а не по дороге, как машины и автобусы? Я хочу чтобы трамваи ездили по дороге!!!
— Понимаешь, трамвай очень тяжёлый, намного тяжелее автобуса или машины. Поэтому ему сделали железные колёса и построили по среди дороги рельсы, чтоб он мог ездить.
— А я всё равно хочу чтобы трамвай ездил по дороге!
— Ну в таком случае он своими колёсами поломал бы дорогу, и тогда не смогли бы ездить автобусы, маршрутки и машины.
— Ну так пусть ему сделают резиновые колёса: я хочу чтобы трамвай ездил по дороге!!!

... и так далее ... помню папаша тогда запарился объяснять своему чаду, почему же всё-таки колёса у трамвая железные и ездит но по рельсам. Но надо отдать папаше должное: он терпеливо объяснял своему чаду всё, чтобы он ни спрашивал, говорил с ребёнком, а не послал его, как это бывает делают родители, которых задолбали их же дети.

... так вот ... к чему это я говорю: к тому, что мне ваше "Я хочу, чтобы imbue делалось автоматически" почему-то очень напоминает "я хочу чтобы трамвай ездил по дороге, а не по рельсам" ...

"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[8]: тысяча третий раз про Юникод
От: pepsicoca  
Дата: 15.10.09 15:17
Оценка:
Здравствуйте, Rakafon, Вы писали:

R>... так вот ... к чему это я говорю: к тому, что мне ваше "Я хочу, чтобы imbue делалось автоматически" почему-то очень напоминает "я хочу чтобы трамвай ездил по дороге, а не по рельсам" ...


R>


А мне Ваше "Для Юникода надо делать imbue" напоминают "рыбе надо зонтик, она же в воде все время". Это же Юникод. Он для того и сделан, чтобы вручную локаль не переключать.
Re[9]: тысяча третий раз про Юникод
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 15.10.09 15:34
Оценка: -1
Здравствуйте, pepsicoca, Вы писали:
P>А мне Ваше "Для Юникода надо делать imbue" напоминают "рыбе надо зонтик, она же в воде все время". Это же Юникод. Он для того и сделан, чтобы вручную локаль не переключать.

А я где-то говорил, что для Юникода надо делать imbue? До меня вообще как-то не совсем доходит фраза "Для Юникода надо делать imbue" ...
imbue надо делать для С++ потокового класса std::wcout, вывод которого в консоль не имеет никакого отношения к юникоду. Почему это надо делать: здесь, а также в соседних идиентичных ветках, которые вы с лёгкой руки расплодили, вам как минимум три человека объяснили почему именно это надо делать, причём раза по два/три каждый.

...

"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[10]: тысяча третий раз про Юникод
От: pepsicoca  
Дата: 15.10.09 15:49
Оценка: +1
Здравствуйте, Rakafon, Вы писали:

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

P>>А мне Ваше "Для Юникода надо делать imbue" напоминают "рыбе надо зонтик, она же в воде все время". Это же Юникод. Он для того и сделан, чтобы вручную локаль не переключать.

R>А я где-то говорил, что для Юникода надо делать imbue? До меня вообще как-то не совсем доходит фраза "Для Юникода надо делать imbue" ...

R>imbue надо делать для С++ потокового класса std::wcout, вывод которого в консоль не имеет никакого отношения к юникоду. Почему это надо делать: здесь, а также в соседних идиентичных ветках, которые вы с лёгкой руки расплодили, вам как минимум три человека объяснили почему именно это надо делать, причём раза по два/три каждый.

R>...


R>


Да тут не три, ту тридцать три человека отметились. Но максимум, что они сказали, это: "в виндах надо делать imbue для std::wcout потому, что так сейчас сделан поток std::wcout". А я Вам говорю — неправильно сейчас сделан поток std::wcout. Его можно и нужно сделать так, что при выводе Юникода не надо будет делать imbue. А то, как он сейчас сделан, это противоречит концепции Юникода.
Re[11]: тысяча третий раз про Юникод
От: andrey.desman  
Дата: 15.10.09 16:06
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>Да тут не три, ту тридцать три человека отметились. Но максимум, что они сказали, это: "в виндах надо делать imbue для std::wcout потому, что так сейчас сделан поток std::wcout". А я Вам говорю — неправильно сейчас сделан поток std::wcout. Его можно и нужно сделать так, что при выводе Юникода не надо будет делать imbue. А то, как он сейчас сделан, это противоречит концепции Юникода.


Ну напиши письмо в микрософт, от нас то ты что хочешь?
Re[12]: тысяча третий раз про Юникод
От: pepsicoca  
Дата: 15.10.09 16:15
Оценка: -1
Здравствуйте, andrey.desman, Вы писали:

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


P>>Да тут не три, ту тридцать три человека отметились. Но максимум, что они сказали, это: "в виндах надо делать imbue для std::wcout потому, что так сейчас сделан поток std::wcout". А я Вам говорю — неправильно сейчас сделан поток std::wcout. Его можно и нужно сделать так, что при выводе Юникода не надо будет делать imbue. А то, как он сейчас сделан, это противоречит концепции Юникода.


AD>Ну напиши письмо в микрософт, от нас то ты что хочешь?


Это не в микрософт, это Страуструпу писать надо. Ну или Алексу Степанову накрайняк.
Re[13]: тысяча третий раз про Юникод
От: Sergey Россия  
Дата: 15.10.09 16:48
Оценка: +1 :)
Здравствуйте, pepsicoca, Вы писали:

P>>>Да тут не три, ту тридцать три человека отметились. Но максимум, что они сказали, это: "в виндах надо делать imbue для std::wcout потому, что так сейчас сделан поток std::wcout". А я Вам говорю — неправильно сейчас сделан поток std::wcout. Его можно и нужно сделать так, что при выводе Юникода не надо будет делать imbue. А то, как он сейчас сделан, это противоречит концепции Юникода.


AD>>Ну напиши письмо в микрософт, от нас то ты что хочешь?


P>Это не в микрософт, это Страуструпу писать надо. Ну или Алексу Степанову накрайняк.


Ну тогда напиши в начале программы _setmode(_fileno(stdout), _O_U16TEXT); (требует хедеров io.h и fcntl.h) и еще раз подумай, кто тут виноват — мокрософт или Страуструп
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: тысяча третий раз про std streams
От: c-smile Канада http://terrainformatica.com
Дата: 15.10.09 18:23
Оценка: :)
Здравствуйте, pepsicoca, Вы писали:

тысяча третий раз говорится что streams в C++ они имплементируют некий вселенский принцип, т.е. не для людей.

Нарисуй себе такое вот:

#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>

class console_stream
{
public:
  console_stream( unsigned t ): h(0) { h = GetStdHandle(t); }
  console_stream& operator << (const wchar_t* str) { write(str); return *this; }
  console_stream& operator << (int i) { wchar_t buf[64]; write(_itow(i,buf,10)); return *this; }
private:
  void write(const wchar_t* str)
  {
    DWORD numchars;
    if(h) WriteConsoleW(h,str,wcslen(str),&numchars,0);
  }
  HANDLE h;
};

console_stream cin(STD_INPUT_HANDLE), cout(STD_OUTPUT_HANDLE), cerr(STD_ERROR_HANDLE);

#pragma setlocale( "russian" )

int main(int argc, char* argv[])
{
  cout << L"Привет мир!\n";
    return 0;
}


и будет тебе хорошо.
Re[2]: тысяча третий раз про std streams
От: Sergey Россия  
Дата: 15.10.09 18:28
Оценка: 1 (1)
Здравствуйте, c-smile, Вы писали:

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


CS>тысяча третий раз говорится что streams в C++ они имплементируют некий вселенский принцип, т.е. не для людей.


CS>Нарисуй себе такое вот:


CS>
CS>#include "stdafx.h"
CS>#include <stdlib.h>
CS>#include <windows.h>

CS>class console_stream
CS>{
CS>public:
CS>  console_stream( unsigned t ): h(0) { h = GetStdHandle(t); }
CS>  console_stream& operator << (const wchar_t* str) { write(str); return *this; }
CS>  console_stream& operator << (int i) { wchar_t buf[64]; write(_itow(i,buf,10)); return *this; }
CS>private:
CS>  void write(const wchar_t* str)
CS>  {
CS>    DWORD numchars;
CS>    if(h) WriteConsoleW(h,str,wcslen(str),&numchars,0);
CS>  }
CS>  HANDLE h;
CS>};

CS>console_stream cin(STD_INPUT_HANDLE), cout(STD_OUTPUT_HANDLE), cerr(STD_ERROR_HANDLE);

CS>#pragma setlocale( "russian" )

CS>int main(int argc, char* argv[])
CS>{
CS>  cout << L"Привет мир!\n";
CS>    return 0;
CS>}
CS>


CS>и будет тебе хорошо.


А че так сложно? Для VC достаточно


#include <iostream>
#include <io.h>
#include <fcntl.h>

int main(int argc, char* argv[])
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    std::wcout << L"Привет мир!";
    return 0;
}
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: тысяча третий раз про Юникод
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 16.10.09 08:07
Оценка:
Здравствуйте, K13, Вы писали:

P>>Выяснилось, что в исходнике кирилическая строка L"привет" хранится в виде кода 1251 (0xef 0xf0 0xe8 0xe2 0xe5 0xf2).


K13>it depends. Вот у нас за такой исходник можно получить по башке, потому что принято решение все исходники сохранять как UTF-8 без BOM.

K13>Иначе возникают проблемы на маке :)

Кстати, сейчас относительно популярен ещё такой метод, как описание кодировки в самом файле и интерпретация её одновременно редакторами и компиляторами. Вот, например, в документации Python:

If a comment in the first or second line of the Python script matches the regular expression coding[=:]\s*([-\w.]+), this comment is processed as an encoding declaration; the first group of this expression names the encoding of the source code file. The recommended forms of this expression are

# -*- coding: <encoding-name> -*-

which is recognized also by GNU Emacs, and

# vim:fileencoding=<encoding-name>

which is recognized by Bram Moolenaar’s VIM. In addition, if the first bytes of the file are the UTF-8 byte-order mark ('\xef\xbb\xbf'), the declared file encoding is UTF-8 (this is supported, among others, by Microsoft’s notepad).

If an encoding is declared, the encoding name must be recognized by Python. The encoding is used for all lexical analysis, in particular to find the end of a string, and to interpret the contents of Unicode literals. String literals are converted to Unicode for syntactical analysis, then converted back to their original encoding before interpretation starts. The encoding declaration must appear on a line of its own.


(я недавно видел обсуждение введения такого ещё в двух языках, но склероз отказывает — не могу вспомнить в каких)

По крайней мере первый вопрос треда это решает.

P>>3. Если в экзешнике уже лежит Юникодная строка, почему кириллица не печатается без явного указания локали функцией imbue? Ведь по Юникоду однозначно определяется начертание символа. И чтобы напечатать Юникод локаль не нужна.

K13>потоки ввода-вывода работают с char. Без указания, какая именно кодировка является активной, не обойтись.

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

K13>"Переключать на ходу" нельзя -- иначе при пайпе/записи в файл нам надо вставлять мета-символы между символами сообщения, а делать это мы не вправе.


Я не понимаю, почему тут надо будет вставлять метасимволы. Метасимволы — это вопрос более высокого уровня протокола, если он есть (в соседнем по сравнению с Windows мире, на ANSI-style терминалах, можно переключать кодировки;)) Поток должен просто отработать директиву "с данного момента перекодирование должно идти в кодировку Z". Умеет он отобразить результат или нет — это уже следующий вопрос, но подобные установки обычно имеют дополнительный признак — что делать в случае невозможности перекодировки (игнорировать, выдавать фиксированный заместительный символ, возбуждать исключение...)
The God is real, unless declared integer.
Re[4]: тысяча третий раз про Юникод
От: MasterZiv СССР  
Дата: 16.10.09 20:39
Оценка:
IID пишет:

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

> неважно сколько раз.

Она может и юникодная, в душе, потенциально. Но
вот как её заставить понимать юникод — не понятно.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: тысяча третий раз про Юникод
От: Sergey Россия  
Дата: 16.10.09 20:55
Оценка:
Здравствуйте, MasterZiv, Вы писали:

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

>> неважно сколько раз.

MZ>Она может и юникодная, в душе, потенциально. Но

MZ>вот как её заставить понимать юникод — не понятно.

Да все так же — mode con codepage select=65001
И будет utf-8 консоль. Или что-то другое требуется?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: тысяча третий раз про Юникод
От: MasterZiv СССР  
Дата: 17.10.09 08:34
Оценка:
Sergey wrote:

> Да все так же — mode con codepage select=65001

> И будет utf-8 консоль. Или что-то другое требуется?

Ну, требовалось -- то UCS-2.
Posted via RSDN NNTP Server 2.1 beta
Re[7]: тысяча третий раз про Юникод
От: Sergey Россия  
Дата: 17.10.09 09:18
Оценка:
Здравствуйте, MasterZiv, Вы писали:

>> Да все так же — mode con codepage select=65001

>> И будет utf-8 консоль. Или что-то другое требуется?

MZ>Ну, требовалось -- то UCS-2.


То, что требовалось, решается одной строчкой в начале программы — _setmode(_fileno(stdout), _O_U16TEXT); Потому что проблема там в том, что функция fputwc в зависимости от настроек для конкретного файла может взять да перевести широкие символы в узкие перед выводом. stdout один, и для wcout и для cout, если перевести его в "широкий" режим, то обычный cout работать перестанет. В общем похоже что пацаны, которые этот кусок CRT писали, просто не стали особо заморачиваться да и переложили проблемы по настройке вывода на пользователя. Хотя могли бы сделать все и по человечески, так чтобы UCS-2 с ANSI в одном файле уживались.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.