Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 08.03.10 22:17
Оценка: :)
Доброго времени суток.
При перекодировке строки в Cp1251 в кодировку UTF-8 возникает ошибка в букве И. Она кодируется как {-48, 63), а должна быть {-48, 104}.

Пример:

String cp1251text = "Иван";
String utf8text = new String(cp1251text.getBytes("utf-8"));

В итоге текст utf8text имеет вид �?ван
С другими буквами русского алфавита как с заглавными так и с прописными все нормально.

Не помогают и более изощренные способы — например перекодировка с помощью всяких там файлов, буферов ввода и прочими шаманскими замолодями.
Даже был такой вариант:

byte[] bytes = utf8text.getBytes();
...
//Заменяем последовательности -48, 63 на -48, 104
utf8text = new String(bytes);

всеравно остается -48, 63. Заколдовано просто...

На MacOS X все нормально. Там нативный UTF-8 и перекодировки все работают без проблем. На Windows XP хуже. Кто что подскажет?
Re: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: C0s Россия  
Дата: 08.03.10 22:39
Оценка: 1 (1)
Здравствуйте, Madjack, Вы писали:

M>String cp1251text = "Иван";
M>String utf8text = new String(cp1251text.getBytes("utf-8"));


1) в Java все строки — UCS-2, поэтому неразумно пытаться называть переменные типа String utf8 или cp1251, раз они таковыми не являются
2) понятие кодировки применимо только к последовательности байтов
3) предлагаю свой вариант твоего примера, после которого должно всё стать ясно:

String text1 = "\u0418\u0432\u0430\u043d";
String text2 = new String(text1.getBytes("utf-8"), "utf-8");
assert text2.equals(text1);
Re: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Blazkowicz Россия  
Дата: 09.03.10 06:47
Оценка:
Здравствуйте, Madjack, Вы писали:

M>При перекодировке строки в Cp1251 в кодировку UTF-8 возникает ошибка в букве И. Она кодируется как {-48, 63), а должна быть {-48, 104}.

Большинство проблем с кодировками именно из-за того что не все понимают что такое кодировка. А кодировка это представление строки в двоичном виде. Строка сама по себе не имеет кодировке. Это просто строка конкретного текста. Кодировки используются для того чтобы строку представить в двоичном виде для последующей передачи или хранения.
Re[2]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 09.03.10 07:07
Оценка:
Здравствуйте, C0s, Вы писали:

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


C0s>
M>>String cp1251text = "Иван";
M>>String utf8text = new String(cp1251text.getBytes("utf-8"));
C0s>


C0s>1) в Java все строки — UCS-2, поэтому неразумно пытаться называть переменные типа String utf8 или cp1251, раз они таковыми не являются

C0s>2) понятие кодировки применимо только к последовательности байтов
C0s>3) предлагаю свой вариант твоего примера, после которого должно всё стать ясно:

C0s>
C0s>String text1 = "\u0418\u0432\u0430\u043d";
C0s>String text2 = new String(text1.getBytes("utf-8"), "utf-8");
C0s>assert text2.equals(text1);
C0s>


Запустил ваш пример. Ошибок не выдало.
Re[2]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 09.03.10 07:09
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

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


M>>При перекодировке строки в Cp1251 в кодировку UTF-8 возникает ошибка в букве И. Она кодируется как {-48, 63), а должна быть {-48, 104}.

B>Большинство проблем с кодировками именно из-за того что не все понимают что такое кодировка. А кодировка это представление строки в двоичном виде. Строка сама по себе не имеет кодировке. Это просто строка конкретного текста. Кодировки используются для того чтобы строку представить в двоичном виде для последующей передачи или хранения.

Я как раз и говорю о представлении строки в двоичном виде. В байтах. Мне как раз и нужно превратить строку в UTF-8 перед отправкой на другой сервер. Так как с приложением работают люди с MacOS, Windows и других операционных систем, то нужно единое представление данных. В UTF-8. А так как в MacOS все данные уже в UTF-8, а на Windows в Cp1251 то нужно чтото делать, чтобы данные на сервер доходили в единой кодировке. И соответственно приходили с него тоже.
Re[3]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: GarryIV  
Дата: 09.03.10 08:58
Оценка:
Здравствуйте, Madjack, Вы писали:

M>>>При перекодировке строки в Cp1251 в кодировку UTF-8 возникает ошибка в букве И. Она кодируется как {-48, 63), а должна быть {-48, 104}.

B>>Большинство проблем с кодировками именно из-за того что не все понимают что такое кодировка. А кодировка это представление строки в двоичном виде. Строка сама по себе не имеет кодировке. Это просто строка конкретного текста. Кодировки используются для того чтобы строку представить в двоичном виде для последующей передачи или хранения.

M>Я как раз и говорю о представлении строки в двоичном виде. В байтах. Мне как раз и нужно превратить строку в UTF-8 перед отправкой на другой сервер. Так как с приложением работают люди с MacOS, Windows и других операционных систем, то нужно единое представление данных. В UTF-8. А так как в MacOS все данные уже в UTF-8, а на Windows в Cp1251 то нужно чтото делать, чтобы данные на сервер доходили в единой кодировке. И соответственно приходили с него тоже.


Поздно пить боржоми когда у тебя уже строка в объекте java.lang.String

A String represents a string in the UTF-16


Сценарий перекодировок такой

byte[] cp1251array = ...;
String str = new String(cp1251array, "cp1251"); // перекодировка CP 1251 -> в String
byte[] utf8array = str.getBytes("UTF-8); // перекодировка String -> UTF-8


Тут вам не C\С++ его строками
WBR, Igor Evgrafov
Re[4]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 09.03.10 09:49
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>Тут вам не C\С++ его строками


Объясню всю ситуацию. Есть некое приложение Java. В нем есть один диалог. В диалоге есть поле ввода JTextField и кнопка JButton. Пользователь запускает приложение, вводит свою фамилию и жмет кнопку. После нажатия кнопки:

//Забираем введенный текст сразу в UTF-8
String fio = new String(jtextfield1.getBytes("utf-8"));
//Отправляем данные юзера на сервак.
soapclient.sendUserFio(base64encode(fio));

Скомпилено и собрано все UTF-8 на макинтоше. На томже макинтоше все работает наура. Проблемы на винде.

Собственно когда строка приходит на сервер то получаем все в UTF-8 за исключением большой заглавной русской буквы И. Она отображается как знак вопроса в ромбике + знак вопроса без ромбика. Никакие шаманства не катят. Подскажите как в String fio получить данные из JTextField в UTF-8 независимо от операционной системы юзера и его кодировки.
Re[3]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Blazkowicz Россия  
Дата: 09.03.10 09:51
Оценка:
Здравствуйте, Madjack, Вы писали:

M>Я как раз и говорю о представлении строки в двоичном виде. В байтах. Мне как раз и нужно превратить строку в UTF-8 перед отправкой на другой сервер. Так как с приложением работают люди с MacOS, Windows и других операционных систем, то нужно единое представление данных. В UTF-8. А так как в MacOS все данные уже в UTF-8, а на Windows в Cp1251 то нужно чтото делать, чтобы данные на сервер доходили в единой кодировке. И соответственно приходили с него тоже.

В твоей ситуации выходит чот строка изначально интерпретировалась неверной кодировкой. В результате чего в объекте находится текст отличный от ожиидаемого. Исправление значения приведенным образом не есть нормальный подход, к тому же, как показывает пример, он не всегда выполним. Нормальный подход должен недопустить появления экземпляра испорченой строки.
Re[5]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Blazkowicz Россия  
Дата: 09.03.10 09:53
Оценка:
Здравствуйте, Madjack, Вы писали:

M>//Забираем введенный текст сразу в UTF-8

M>String fio = new String(jtextfield1.getBytes("utf-8"));

WTF?
Re[6]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 09.03.10 09:58
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

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


M>>//Забираем введенный текст сразу в UTF-8

M>>String fio = new String(jtextfield1.getBytes("utf-8"));

B>WTF?

А по конкретнее...
Re[4]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 09.03.10 09:59
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

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


M>>Я как раз и говорю о представлении строки в двоичном виде. В байтах. Мне как раз и нужно превратить строку в UTF-8 перед отправкой на другой сервер. Так как с приложением работают люди с MacOS, Windows и других операционных систем, то нужно единое представление данных. В UTF-8. А так как в MacOS все данные уже в UTF-8, а на Windows в Cp1251 то нужно чтото делать, чтобы данные на сервер доходили в единой кодировке. И соответственно приходили с него тоже.

B>В твоей ситуации выходит чот строка изначально интерпретировалась неверной кодировкой. В результате чего в объекте находится текст отличный от ожиидаемого. Исправление значения приведенным образом не есть нормальный подход, к тому же, как показывает пример, он не всегда выполним. Нормальный подход должен недопустить появления экземпляра испорченой строки.

Ну так я обратился на форум чтобы мне помогли организовать нормальный подход. Так как у самого не получается.
Re[7]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Blazkowicz Россия  
Дата: 09.03.10 10:02
Оценка:
Здравствуйте, Madjack, Вы писали:

M>>>String fio = new String(jtextfield1.getBytes("utf-8"));

B>>WTF?
M>А по конкретнее...
У JTextField вроде бы нет такого метода. И для чего здесь указание кодировки, если JTextField и так возвращает строку?
Re[5]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: hrensgory Россия  
Дата: 09.03.10 10:05
Оценка:
09.03.2010 12:49, Madjack пишет:

> //Забираем введенный текст сразу в UTF-8

> String fio = new String(jtextfield1.getBytes("utf-8"));

Проблема здесь. Это бессмысленное с точки зрения java деяние, т.к.
реально вызовется что-то вроде.

String fio = new String(jtextfield1.getBytes("utf-8"),
платформо_зависимая_кодировка_по_умолчанию);

А вам скорее всего нужно это:

String fio = field.getText(); // или что там нужно
byte[] bytes = fio.getBytes("utf-8"); // если дальше нужны именно bytes

Поищите статью Сергея Астахова "Java. Русские буквы и не только" — мне
после длительного программирования на C именно она помогла понять что я
делал неправильно.

--
WBR,
Serge.
Posted via RSDN NNTP Server 2.1 beta
Re[8]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 09.03.10 10:14
Оценка: -1
Здравствуйте, Blazkowicz, Вы писали:

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


M>>>>String fio = new String(jtextfield1.getBytes("utf-8"));

B>>>WTF?
M>>А по конкретнее...
B>У JTextField вроде бы нет такого метода. И для чего здесь указание кодировки, если JTextField и так возвращает строку?

Пардон. String text = new String(jtextfield1.getText().getBytes("utf-8"));
Если использовать String text = jtextfield1.getText(); то возвращается строка в текущей кодировке системы. А мне нужен уже Utf-8.
Re[6]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Madjack  
Дата: 09.03.10 10:18
Оценка:
Здравствуйте, hrensgory, Вы писали:

H>09.03.2010 12:49, Madjack пишет:


>> //Забираем введенный текст сразу в UTF-8

>> String fio = new String(jtextfield1.getBytes("utf-8"));

H>Проблема здесь. Это бессмысленное с точки зрения java деяние, т.к.

H>реально вызовется что-то вроде.

H>String fio = new String(jtextfield1.getBytes("utf-8"),

H>платформо_зависимая_кодировка_по_умолчанию);

H>А вам скорее всего нужно это:


H>String fio = field.getText(); // или что там нужно

H>byte[] bytes = fio.getBytes("utf-8"); // если дальше нужны именно bytes

H>Поищите статью Сергея Астахова "Java. Русские буквы и не только" — мне

H>после длительного программирования на C именно она помогла понять что я
H>делал неправильно.

H>--

H>WBR,
H>Serge.

Мне нужны не байты. До байтов я докапался когда искал проблему, в каком месте коржется буква И. Механизм прост. Пользователь вводит строку, мне нужно эту строку получить в utf-8 и отправить на удаленный сервер.

H>String fio = field.getText(); // или что там нужно


Здесь строка fio будет в кодировке системы. Если на винде то в cp1251. А мне нужна в utf-8. Соответственно вместо:
String text = jtextfield1.getText();
bytes[] bytes = text.getBytes("utf-8");
String utftext = new String(bytes);

я пишу одной строчкой
String text = jtextfield1.getText().getBytes("utf-8");
Re[5]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Golden Wolf http://not-null.com
Дата: 09.03.10 10:18
Оценка:
Здравствуйте, Madjack, Вы писали:

M>Собственно когда строка приходит на сервер то получаем все в UTF-8 за исключением большой заглавной русской буквы И. Она отображается как знак вопроса в ромбике + знак вопроса без ромбика. Никакие шаманства не катят. Подскажите как в String fio получить данные из JTextField в UTF-8 независимо от операционной системы юзера и его кодировки.


А вы уверенны, что проблема ДО передачи данных на сервер?
Каким образом данные поступают на сервер?
Re[9]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Blazkowicz Россия  
Дата: 09.03.10 10:20
Оценка:
Здравствуйте, Madjack, Вы писали:

M>Пардон. String text = new String(jtextfield1.getText().getBytes("utf-8"));

M>Если использовать String text = jtextfield1.getText(); то возвращается строка в текущей кодировке системы. А мне нужен уже Utf-8.
Ну, вот. Ты снова не разобрался. Хотя становишься в защитную позу
Автор: Madjack
Дата: 09.03.10
. В строке
String text = jtextfield1.getText()
нет понятия кодировки, так как здесь нет никакого двоичного представления.
Re[10]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И
От: Madjack  
Дата: 09.03.10 10:24
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

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


M>>Пардон. String text = new String(jtextfield1.getText().getBytes("utf-8"));

M>>Если использовать String text = jtextfield1.getText(); то возвращается строка в текущей кодировке системы. А мне нужен уже Utf-8.
B>Ну, вот. Ты снова не разобрался. Хотя становишься в защитную позу
Автор: Madjack
Дата: 09.03.10
. В строке

B>String text = jtextfield1.getText()
B>нет понятия кодировки, так как здесь нет никакого двоичного представления.

Да я не становлюсь в позу=) Я просто проверил все на практике. Если не делать тех манипуляций с перекодировками то до сервера приходит строка в cp1251.
Re[11]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И
От: Blazkowicz Россия  
Дата: 09.03.10 10:29
Оценка:
Здравствуйте, Madjack, Вы писали:

M>Да я не становлюсь в позу=) Я просто проверил все на практике. Если не делать тех манипуляций с перекодировками то до сервера приходит строка в cp1251.

Логично предположить что манипуляции производятся ошибочно и решение должно быть другое.
Re[7]: Перекодировка Cp1251 -> UTF-8 или заглавная буква "И"
От: Blazkowicz Россия  
Дата: 09.03.10 10:30
Оценка:
Здравствуйте, Madjack, Вы писали:

M>Мне нужны не байты. До байтов я докапался когда искал проблему, в каком месте коржется буква И. Механизм прост. Пользователь вводит строку, мне нужно эту строку получить в utf-8 и отправить на удаленный сервер.

Для удаленной передачи вам нужны именно байты. Иначе никак.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.