Перейти к содержимому


Фото

Странности со строками, кириллицей и нулевым элементом


  • Чтобы отвечать, сперва войдите на форум
12 ответов в теме

#1 Ripper Опубликовано 02 Июнь 2010 - 15:43

Ripper
  • Свои
  • 497 Сообщений:
  • Павел Рустанович
#include <stdio.h>

int main(int argc, char *argv[]) {
	unsigned char *word1 = "Привет, Мир!";
	unsigned char *word2 = "Hello World!";
	unsigned char *word3 = "Latinitsya";
	unsigned char *word4 = "Ещё что-то";
	
	printf("word1[0] (кириллица) == %i\n", word1[0]);
	printf("word2[0] == %i\n", word2[0]);
	printf("word3[0] == %i\n", word3[0]);
	printf("word4[0] (кириллица) == %i\n", word4[0]);
	printf("const[0] (кириллица) == %i\n", (const unsigned char)"О, кириллица"[0]); // Да хоть так
	return 0;
}

Вывожу именно int, т.к. 208 символ не хочет отображаться.

word1[0] (кириллица) == 208
word2[0] == 72
word3[0] == 76
word4[0] (кириллица) == 208
const[0] (кириллица) == 208


Почему и зачем в строках с кириллицей первым символом идёт какой-то 208-ой (и что это такое) ?

Изменено: Ripper, 02 Июнь 2010 - 15:44

post-2756-0-28658900-1472313042.png


#2 Syrano Опубликовано 02 Июнь 2010 - 16:29

Syrano
  • Свои
  • 9 630 Сообщений:
  • Владимир Зайцев

Почему и зачем в строках с кириллицей первым символом идёт какой-то 208-ой (и что это такое) ?

В какой кодировке у тебя строки? Похоже, что это utf-8. В нем один символ может кодироваться последовательностью до 6 байт. wiki про utf-8.

Так, например, русские буквы представлены двумя байтами каждая:
0xD0xx или 0xD1xx.
0xD0 == 208

С нами сила Алхазашвили!


#3 Ripper Опубликовано 02 Июнь 2010 - 17:22

Ripper
  • Свои
  • 497 Сообщений:
  • Павел Рустанович
Да, выходит, что utf-8. А как заставить gcc превращать все мои строки в ascii ? Т.к. с юникодом пока что не хочется возиться

post-2756-0-28658900-1472313042.png


#4 Syrano Опубликовано 02 Июнь 2010 - 17:32

Syrano
  • Свои
  • 9 630 Сообщений:
  • Владимир Зайцев

Да, выходит, что utf-8. А как заставить gcc превращать все мои строки в ascii ? Т.к. с юникодом пока что не хочется возиться

В редакторе, в котором пишешь код, настрой нужную тебе кодировку. Или переведи написанный файл в нужную кодировку с помощью iconv.

То есть дело не в gcc, а в том, что у тебя в константы кладется. То есть, в какой кодировке текст программы.

С нами сила Алхазашвили!


#5 Ripper Опубликовано 03 Июнь 2010 - 8:28

Ripper
  • Свои
  • 497 Сообщений:
  • Павел Рустанович
Ну gcc же нормально воспринимает программный код в utf-8, не смотря на несколько байт для представления одного символа. Наверняка он может сам перекодировать константы

post-2756-0-28658900-1472313042.png


#6 Денис Опубликовано 03 Июнь 2010 - 8:30

Денис
  • Genius loci
  • 6 898 Сообщений:
  • Денис Сумин
gcc все равно, в какой кодировке написан программный текст. Он прочитывает заголовок, в котором описана кодировка (или как там в текстовом файле указывается она) и работает в этой кодировке, кодировке программного текста.

#7 Syrano Опубликовано 03 Июнь 2010 - 11:40

Syrano
  • Свои
  • 9 630 Сообщений:
  • Владимир Зайцев

Ну gcc же нормально воспринимает программный код в utf-8, не смотря на несколько байт для представления одного символа. Наверняка он может сам перекодировать константы

Не может. У него нет такой функциональности. Латиница -- она одинаковая и во всех однобайтных кодировках и в UTF-8. Так оно устроено! И UTF так задуман!
Для компиллятора есть понятие: строковая константа. Это то, что заключено в двойные кавычки. Найдя символ двойной кавычки (который тоже везде одинаковый, как и всякие точки-запятые), компиллятор просматривает текст дальше в поисках закрывающей кавычки. Все, что между ними он считает строковой константой. Он не анализирует, что именно туда попадает, поэтому ему нет разницы, в какой кодировке эти строчки. Он просто их побайтно копирует. Есть небольшое исключение -- символ '\'. Его компиллятор ищет наравне с кавычками, и обрабатывает специфическим образом.

Так что gcc тебя не спасет.

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

Решишь -- пиши. Тогда обсудим, что делать дальше. :-)

С нами сила Алхазашвили!


#8 Syrano Опубликовано 03 Июнь 2010 - 11:42

Syrano
  • Свои
  • 9 630 Сообщений:
  • Владимир Зайцев

gcc все равно, в какой кодировке написан программный текст.

Это верно.

Он прочитывает заголовок, в котором описана кодировка (или как там в текстовом файле указывается она) и работает в этой кодировке, кодировке программного текста.

А вот это неверно.
В чистом текстовом файле (каковым, например, является исходник на c++), кодировка файла не указывается нигде. И gcc даже и не задумывается, в какой кодировке исходник, потому что все его ключевые слова и знаки во всех кодировках выглядят одинаково.

С нами сила Алхазашвили!


#9 Денис Опубликовано 03 Июнь 2010 - 11:46

Денис
  • Genius loci
  • 6 898 Сообщений:
  • Денис Сумин
Ага, осознал. А всякие текстовые редакторы и браузеры задумываются, в какой кодировке текстовый файл и по каким-то признакам определяют это, так?

#10 Syrano Опубликовано 03 Июнь 2010 - 11:57

Syrano
  • Свои
  • 9 630 Сообщений:
  • Владимир Зайцев

Ага, осознал. А всякие текстовые редакторы и браузеры задумываются, в какой кодировке текстовый файл и по каким-то признакам определяют это, так?

Всякие текстовые редакторы и браузеры не могут ограничиться только ключевыми словами младшей части ascii-таблицы. Поэтому им, конечно, приходиться осознавать, с чем же они работают.
Как определить? В большинстве современных форматов кодировка указывается явно в каком-нибудь заголовке документа или его части.
Если же такого указания нет, то восстановить кодировку можно по словарям и всяким внешним признакам. Но это уже эвристика.

С нами сила Алхазашвили!


#11 KiberGus Опубликовано 03 Июнь 2010 - 13:19

KiberGus
  • Genius loci
  • 6 561 Сообщений:
  • Алексей Гусейнов

Да, выходит, что utf-8. А как заставить gcc превращать все мои строки в ascii ? Т.к. с юникодом пока что не хочется возиться

Не используй кирилицу. ASCII не содержит кирилицы и, поэтому, ты не можешь работать с крилицей в ascii. Ты можешь использовать однобайтную кодировку, поддерживающую кирилицу, например cp1251 или koi8-r, если хочешь получить кучу проблем в виде несовместимости своей программы со всеми остальными. В настоящий момент все новые программы либо умеют работать с произвольными кодировками, либо только с utf, в последнем случае чаще всего с utf-8 (часто в качестве внутреннего представления используется utf-16). Причем порой встречаются случаи, когда разработчики сознательно отключают поддержку чего-либо кроме utf, чтобы заставить пользователей наконец начать пользоваться одной кодировкой и не иметь гемороя с зоопарком.
P.S. Кстати, MP3 не поддержвает названия песен кирилицей. Разработчики забыли, что есть иные языки, кроме английского. Из-за этого вы часто можете видеть крякозябры вместо названий в композициях.
Зато, обладая единственной в мире подводной орбитальной группировкой спутников глонасс...
gentoo.gif

#12 Syrano Опубликовано 03 Июнь 2010 - 13:40

Syrano
  • Свои
  • 9 630 Сообщений:
  • Владимир Зайцев

Не используй кирилицу. ASCII не содержит кирилицы и, поэтому, ты не можешь работать с крилицей в ascii. Ты можешь использовать однобайтную кодировку, поддерживающую кирилицу, например cp1251 или koi8-r, если хочешь получить кучу проблем в виде несовместимости своей программы со всеми остальными. В настоящий момент все новые программы либо умеют работать с произвольными кодировками, либо только с utf, в последнем случае чаще всего с utf-8 (часто в качестве внутреннего представления используется utf-16). Причем порой встречаются случаи, когда разработчики сознательно отключают поддержку чего-либо кроме utf, чтобы заставить пользователей наконец начать пользоваться одной кодировкой и не иметь гемороя с зоопарком.
P.S. Кстати, MP3 не поддержвает названия песен кирилицей. Разработчики забыли, что есть иные языки, кроме английского. Из-за этого вы часто можете видеть крякозябры вместо названий в композициях.

Глобально Леша прав. И вообще, конечно, надо научиться работать именно с UTF. Но прежде всего надо разумно подойти к задаче. Если понятно, что это какая-нибудь полезная мелочь, в которой на первом месте стоит функционал, не связанный с вводом/выводом кириллицы, и вообще говоря, можно хоть транслитом все написать, и задача будет решена, то заморачиваться сейчас с UTF не обязательно. Тут важно правильно понять, что же именно хочется получить (этого ответа и жду).
А если это "хочу поиграться, чтобы чему-нибудь научиться", или же кириллица играет важную роль в программе, то тут согласен с Лешей, лучше отказаться от однобайтовых кодировок, научиться работать с UTF, и в дальнейшем использовать только UTF.

С нами сила Алхазашвили!


#13 Ripper Опубликовано 03 Июнь 2010 - 16:32

Ripper
  • Свои
  • 497 Сообщений:
  • Павел Рустанович
Буду разбираться с юникодом. Всем спасибо!

post-2756-0-28658900-1472313042.png





0 пользователей читают эту тему

0 пользователей, 0 гостей, 0 невидимых