На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Каркас таблицы (псевдографика) выводится вопросами в консоли , чистый СИ, visual studio 2010
    Всем хай! Сходу к делу!

    Есть код:
    ExpandedWrap disabled
          //SetConsoleOutputCP(866);
          //SetConsoleCP(866);
          printf("  ╔═════╦════════════════════╦════════════════════╗\n");//  ╚╔ ╩ ╦ ╠ ═ ╬ ╣ ║ ╗ ╝
          printf("  ║  №: ║       Марка     ║         ФИО        ║\n");
          printf("  ╠═════╬════════════════════╬════════════════════╣\n");


    при выводе вся псевдографика меняется на знаки ВОПРОСОВ (выглядит чертовски коряво).
    я вроде понимаю, что дело в кодировке, но как не пытался играться с setlocale, SetConsoleCP и пр. никак не могу добиться распечатки правильного каркаса...

    подскажите, как быть-то?
      ИМХО дело в кодировке исходного текста. В 1251 символов псевдографики нет вообще, так что строковые литералы будут содержать что угодно, но не их. Смени кодирование на 866, вывод в консоль даже не придётся настраивать.
        Цитата Qraizer @
        ИМХО дело в кодировке исходного текста. В 1251 символов псевдографики нет вообще, так что строковые литералы будут содержать что угодно, но не их. Смени кодирование на 866, вывод в консоль даже не придётся настраивать.

        Qraizer, а ведь ты правильную идею говоришь, т к я помню, что когда начал в коде пропечатывать эти АЛЬТ-символы (через малую правую клавиатуру), а потом нажал компиляция, то VS выдала какое-то сообщение о том, что мол кодировка страницы будет сменена на что-то там. Я не придал этому значения, даже сообщение до конца не дочитал. и вот сейчас получил проблемы...

        Цитата Qraizer @
        Смени кодирование на 866

        программно или через опции VS??
        P.S. я совсем запутался с этой псевдографикой в консоли VS. Вроде несложно все это, но нужно понимать нюансы очень хорошо
          Цитата FasterHarder @
          программно или через опции VS??
          В .c-файле. В Far-е это примерно так:
          Прикреплённая картинка
          Прикреплённая картинка
            Уходите вы от этих однобайтовых кодировок!
            Юникод прекрасно сохраняет псевдографику.
            Писать нужно в Юникоде, а выводить уже как
            тянет кодировка консоли.

            user posted image
              пишу код в среде Visual Studio. Там есть Файл - Дополнительные параметры сохранения
              Прикреплённая картинка
              Прикреплённая картинка


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

              Какую из списка кодировку нужно поставить + всякие setlocale никак не мешают здесь?
                FasterHarder, надо отделить пчел от меда :lol:

                Однобайтовые кодировки уже давно - анахронизм. Это аксиома, если желаешь чтобы твои проги были user frendly.
                Многобайтовых кодировок множество, основное распространение получила UTF-8, т.к. в общем зачете для разработки программ в ней больше плюсов, чем минусов по сравнению, к примеру с UTF-16 или UTF-32. Поэтому пользуем строго UTF-8.

                При сохранении документов в кодировке UTF-8 нередко используют спецификацию BOM (сокращенно от Byte Order Mark). Использование UTF-8 с BOM - затея ошибочная, по сути, и Мелкософт тут лоханулся. Ибо проблемы порядка байтов для UTF-8 не существует! BOM актуален для UTF-16 и UTF-32. Более того, спецификация Unicode 5.0 настоятельно рекомендует не использовать BOM с UTF-8 (см.2.6 спецификации):

                Цитата
                ...
                Use of a BOM is neither required nor recommended for UTF-8, but may be encountered in contexts where UTF-8 data is converted from other encoding forms that use a BOM or where the BOM is used as a UTF-8 signature.
                ...

                А теперь про использование ... Тут два этапа - разработки и исполнения.

                Этап разработки

                В редакторе используем UTF-8 и пользуемся всеми плюшками обширной таблицы кодов. Компиляторы этому не противятся и работают прекрасно. Естественно, все строковые константы имеют многобайтную кодировку.

                Этап исполнения

                Вот тут нужно быть аккуратнее. При использовании API операционных систем следует выбирать варианты функции, которые работают с многобайтными кодировками. Однако, перед использованием, к примеру, WinAPI-функций, UTF-8 строки нужно перекодировать в UCS-2 (примерно совпадает с UTF-16).

                Что же касается вывода UTF-8 строк в консоль, нужно смотреть свойства консоли. Если консоль работает непосредственно с UTF-8, то никаких преобразование не требуется (современные консоли GUI, или при определенных настройках, системные консоли *nix). Что касается вывода в "консоль" (хотя она не является таковой) русифицированной Windows - там cp866. Соответственно, требуется перекодировка. Тут два варианта:

                1) Использовать возможности Windows (пример)
                2) Использовать возможности С++ (пример)

                Ну вот как-то так.
                  Цитата FasterHarder @
                  Какую из списка кодировку нужно поставить + всякие setlocale никак не мешают здесь?
                  Ну последняя же. Кириллица (DOS), 866-ая. И никаких локалей.
                  JoeUser, от UTF-8 больше проблем. Хотя бы из-за sizeof(char[]) != strlen(char[])+1. Я, вон, где-то выкладывал обобщённую функцию сортировки многобайтовой строки, там на целый экран манипуляций с символами.
                    Цитата Qraizer @
                    JoeUser, от UTF-8 больше проблем

                    Повторюсь - есть плюсы, есть минусы. Строки с символами переменной длины хуже парсятся, сортируются - это минус. Но хорошо экономят пространство хранения, обеспечивая широкий набор глифов - это жирный плюс (допустим по сравнению с UTF-32). Что же касается обработки большого объема данных, так, имхо, их нужно не самому решать - а возложить это на SQL БД.

                    Добавлено
                    ЗЫ: Нет, не отрицаю, если речь идет о создании софта для местного рынка или для себя, и не нужно, к примеру, использовать какое-то расширенное оформление - можно и не заморачиваться, а взять по старинке cp866.
                      Цитата Qraizer @
                      Ну последняя же. Кириллица (DOS), 866-ая. И никаких локалей.

                      да, это кодировка решила все проблемы :yes: спс
                      протестил на этом примере:
                      ExpandedWrap disabled
                        #include "stdafx.h"
                        #include <stdio.h>
                        #include <conio.h>
                         
                        int _tmain(int argc, _TCHAR* argv[])
                        {
                            printf("  ╔═════╦════════════════════╦════════════════════╗\n");//  ╚╔ ╩ ╦ ╠ ═ ╬ ╣ ║ ╗ ╝
                            printf("Привет, мир!");
                            getch();
                            return 0;
                        }

                      вывод:
                      Прикреплённая картинка
                      Прикреплённая картинка


                      кстати, это кодировку я проверял на исходом проекте: русский текст печатался кракозябрами, а псевдографиками - вопросами. А вот новый проект(код чуть выше) отработал на ура без всяких локалей. Ведать что-то там сбилось в исходном проекте.

                      В общем, нужно СРАЗУ при создании проекта переходить на эту кодировку и все, проблем не будет. Хотя, нужно проверить, считывает ли русский текст с клавиатуры правильно (не придется ли переключаться на кодировку 1251)...

                      Добавлено
                      проверил. считывается русский текст отлично.

                      В общем НАДО СРАЗУ СТАВИТЬ ЭТУ КОДИРОВКУ ДА И ВСЕ!
                        Цитата FasterHarder @
                        В общем НАДО СРАЗУ СТАВИТЬ ЭТУ КОДИРОВКУ ДА И ВСЕ!

                        Это, как бы, тебе повезло.
                        А если нужно получать строки из Linux или наоборот - слать туда ?
                        Чаще всего у Виндус используется 4 кодировки - utf16, utf8, CP1251, CP866.
                        Штатными средствами Виндус можно преобразовать любую из них в любую из них.
                          чтобы не создавать новую тему напишу здесь, т к появилась проблема, связанная с кодовой страницей и псевдографикой в коде

                          из вышенаписанного было понятно, чтобы каркас таблицы нормально отображался нужно ставить кодировку "Кириллица ДОС - 866" и все круто работало.
                          но вот сегодня появилась проблема с настройкой ЗАГОЛОВКА консольного окна вывода

                          ExpandedWrap disabled
                                // настройка заголовка консольного окна
                                static const TCHAR* title = TEXT("Это заголовок консольного окна вывода русскими буквами");
                                SetConsoleTitle(title);


                          и вместо русских символов отображаются кракозябры(
                          как это побороть???

                          зы: а вообще с кодировкой можно хапнуть лютые проблемы на ровном месте, как я понял. Всякие ЮТФ-8, ЮНИКОД и пр. пр. ужс...
                            И снова отсылаю к кодировке .c-файла. Был же совет об использовании 866 страницы. Шрифт, используемый в окне, будет использоваться и в заголовке. Возможно, влияет версия консоли, но это надо в разделе WinAPI уточнять.

                            P.S. Если приложение юникодовое, то TEXT() по идее правильно сработает на тексте в кодировке 1251 страницы, т.к. именно на это рассчитывает компилятор, когда char[]ный литерал будет компилить в wchar_t[]шный.
                              у меня псевдографика табличная в приложении, поэтому сразу при создании проекта выставил 866 кодировку и не прописывал всякие setlocale, SetConsoleCP, ... и все было зашибись, пока не попытался сделать русскими заголовок консольного окна

                              проверил на кодировке 1251, да, там заголовок из РЯ правильно отображается

                              от этого ВИНАПИ никуда не деться) но там такая шняга непонятная) потребуются десятки тысяч лет, чтобы выучить винапи
                              ладно, придется значит отказаться от русских букв в заголовке, когда кодировка страницы 866 стоит. ведь псевдографика редко, когда требуется...
                                Цитата FasterHarder @
                                проверил на кодировке 1251, да, там заголовок из РЯ правильно отображается
                                Значит приложение юникодное. Сделай тогда принудительный ANSI-вызов. Типа:
                                ExpandedWrap disabled
                                  static const char* title = "Это заголовок консольного окна вывода русскими буквами";
                                  SetConsoleTitleA(title);
                                  прописал, в итоге компиллер ругаться стал на этот вызов SetConsoleTitleA:
                                  Цитата
                                  IntelliSense: argument of type "const TCHAR *" is incompatible with parameter of type "LPCSTR"


                                  какие типы страшные: TCHAR, LPCSTR)

                                  Добавлено
                                  все, понял, не заметил, что ты исправил на char*
                                  но это не помогло все равно...
                                  в заголовке печатается совсем мало знаков и какие-то кракозябры

                                  Добавлено
                                  кодировка у проекта стоит 866, если что
                                    Цитата FasterHarder @
                                    кодировка у проекта стоит 866, если что
                                    Я не знаю, что такое "кодировка проекта", я знаю, что такое "кодировка файла исходного текста".
                                    Тогда лучше у виндузятников спросить. Я лично проверил: для ANSI-приложения — кодировка файла 866, всё пучком, кодировка 1251 — титл нечитаемый; для UNICODE-приложения — кодировка файла 866, титл нечитаемый, но по-другому, кодировка 1251 — всё пучком.
                                      Цитата FasterHarder @
                                      но это не помогло все равно...
                                      в заголовке печатается совсем мало знаков и какие-то кракозябры

                                      Попробуй так:
                                      ExpandedWrap disabled
                                        static const WCHAR* title = L"Это заголовок консольного окна вывода русскими буквами";
                                            SetConsoleTitleW(title);

                                      ---
                                      И вообще ты всё это зря затеял.
                                      Надо было оставить проект обычным - со стандартной кодировкой исходника.
                                      Таблицу рисовать может и не очень наглядно в исходнике, но это же константы:
                                      ExpandedWrap disabled
                                        // ╔ - \xc9
                                        // ═ - \xcd
                                        // ╦ - \xcb
                                        // ╗ - \xbb
                                         
                                         printf("\xc9\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcb\xcd\xcd\xbb\n");

                                      ---
                                      Но самое удобное, очевидно, это взять твою строку из 1-го сообщения
                                      в формате UTF-16:
                                      ExpandedWrap disabled
                                         printf("  ╔═════╦════════════════════╦════════════════════╗\n");

                                      и использовать её так:
                                      ExpandedWrap disabled
                                        static const WCHAR* pStr = L"╔═════╦════════════════════╦════════════════════╗";
                                        // преобразуем WCHAR -> OEM
                                         const char* p = Wchar2Oem(pStr);
                                         printf("%s\n",p);

                                      И тогда всё получится удобно.
                                      Надо только сделать конвертер.
                                      Сообщение отредактировано: ЫукпШ -
                                        Цитата ЫукпШ @
                                        Попробуй так:

                                        :no: , опять кракозябры, но уже ДРУГИЕ кракозябры, не те, которые были до этого)

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

                                        также при считывании файлов с диска *.txt с русским содержимым, тоже не все чисто
                                        а еще иногда при работе с *.csv-файлами, тоже проблемы с кодировкой

                                        надо будет как-нибудь сесть и основательно разобраться с этой кодировкой и сделать шпаргалку себе, какую куда преобразовывать, что задает кодировку, операционнка или Visual studio и пр. пр. моменты
                                          Цитата FasterHarder @
                                          Цитата ЫукпШ @
                                          Попробуй так:

                                          :no: , опять кракозябры, но уже ДРУГИЕ кракозябры, не те, которые были до этого)

                                          Это означает, что кодировка твоего исходника - не CP1251.
                                          Что плохо, поскольку этот вариант порождает массу проблем.
                                          При этом актуальность наличия разнообразных перекодировщиков
                                          текстовых строк только возрастает.
                                          ---
                                          Что означает строка:
                                          ExpandedWrap disabled
                                            static const WCHAR* title = L"Это заголовок консольного окна вывода русскими буквами";

                                          ??
                                          буквально следующее:
                                          "Дорогой друг компилятор ! У меня есть строчка "Это заголовок консольного окна вывода русскими буквами"
                                          в кодировке CP1251. Я поставил вначале L. Вот так:
                                          L"Это заголовок консольного окна вывода русскими буквами".
                                          Это значит, что я хочу, чтобы эта строчка в сегменте констант исполнимой программы
                                          была в кодировке UTF-16.
                                          Я передам её функции SetConsoleTitleW и увижу правильные буквы в заголовке. "

                                          А если кодировка исходной строки другая, (а компилятор об этом ведь не знает)
                                          то все его преобразования бессмысленны.
                                          Заставить программу работать можно. Но для этого должно быть
                                          дополнительное преобразование текста.
                                          Если исходник в формате OEM, тогда:
                                          ExpandedWrap disabled
                                            static const char* title = "Это заголовок консольного окна вывода русскими буквами";
                                            const char* p = Oem2Wcar(title);
                                            SetConsoleTitleW(p);

                                          Но это просто не удобно. И к тому же лишает возможности
                                          использовать это:
                                          ExpandedWrap disabled
                                            L"Это заголовок консольного окна вывода русскими буквами";

                                          Возможны и более сложные варианты.
                                          Например, исходник - в кодировке ОЕМ, а в настройках проекта стоит "USE UNICODE..."
                                          Тогда компилятор начнёт по-умолчанию конверсию CP1251 -> UTF16 всех текстовых строк.
                                          А они - в кодировке ОЕМ.. получатся сплошные неприятности.
                                          ---
                                          Предложение менять кодировку исходника для изменения поведения программы - крайне не удачная идея.
                                          Сообщение отредактировано: ЫукпШ -
                                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                          0 пользователей:


                                          Рейтинг@Mail.ru
                                          [ Script execution time: 0,1140 ]   [ 22 queries used ]   [ Generated: 2.05.24, 06:34 GMT ]