Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Из getchar на консоль - получаю кракозяблы для рус 
:(
    Опции темы
Compositum
  Дата 9.5.2011, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Изучаю С, читаю Кернигана и Ритчи, упр. 1.5.
Написал на С такой код:
Код

#include<stdio.h>

main()
{
    int c;
    while ((c = getchar()) != EOF)
        //Печатаю каждый символ и заодно значения на проверку равенства/неравенства EOF
        printf("char: %c\tc == EOF: %d\tc != EOF: %d\n", c, c == EOF, c != EOF);

    printf("******************\n");
    //Сейчас переменная c содержит значение EOF
    printf("char: %c\tc == EOF: %d\tc != EOF: %d\n", c, c == EOF, c != EOF);

    printf("******************\n");
    //Смотрю числовые значения символьной константы EOF и её логического антипода: !EOF
    

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

user posted image

Как правильно решать эту проблему и чем она собственно обусловлена (я понимаю, что что-то с кодировкой, но...)?

Это сообщение отредактировал(а) Compositum - 9.5.2011, 20:14
PM   Вверх
bsa
Дата 10.5.2011, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Это особенности кодировки UTF-8. Символы, не входящие в ASCII, кодируются более чем одним байтом. Чтобы победить проблему необходимо использовать юникод (wchar_t вместо char, setlocale(LC_ALL, ""); а затем mbtowc() и wctomb() для преобразования в юникод и обратно, wprintf() для вывода)
PM   Вверх
Compositum
Дата 10.5.2011, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(bsa @ 10.5.2011,  10:47)
Это особенности кодировки UTF-8. Символы, не входящие в ASCII, кодируются более чем одним байтом. Чтобы победить проблему необходимо использовать юникод (wchar_t вместо char, setlocale(LC_ALL, ""); а затем mbtowc() и wctomb() для преобразования в юникод и обратно, wprintf() для вывода)

Спасибо за ответ. Правда, если честно, легче мне не стало. Я читаю указанную выше книгу последовательно и до перечисленных вами функций пока не дошел (да и вряд ли они описаны в ней). Полез в интернет разбираться, что это за "широкие символы", что они собой представляют и каков механизм работы с ними. Определение, данное в википедии, на самом деле - залепуха (имхо), которая не разъясняет сути вопроса. Кстати, по указанной мною ссылке написано, что wchar_t это не юникод...

В общем - всё печально... Пока что продолжу изучение С по Ритчи с переходом на Шильдта, надеюсь, что второй этот вопрос где-то разжевал... Текстовые файлы буду в процессе обучения обрабатывать только такие, которые содержат текст на буржуйском, раз с русским проблема...

Это сообщение отредактировал(а) Compositum - 10.5.2011, 20:04
PM   Вверх
bsa
Дата 10.5.2011, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Compositum, ты правильно решил отказаться от русского при обучении. Лишние проблемы.

wide char - это действительно не юникод. Это лишь тип, позволяющий хранить более 256 кодов. Под Windows, например, размер переменной этого типа 2 байта, а под *nix - 4.
Юникод (причем, определенный) используется при вводе/выводе данных.
Когда будешь писать "боевые" программы проблемы этой скорее всего не будет. Так как ты наверняка будешь использовать какой-нибудь фреймворк, в котором это уже решено.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0446 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.