Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.03.2023, 16:59   #1
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию как добавить кодировку

Приветствую уважаемые.

По умолчанию в code::blocks - UTF-8
В Виндовс - 1251

После компиляции (в GCC) если в заголовке окна русские буквы, то отображаются "кракозябры".

Как исправить чтобы русский текст отображался корректно?

В шаблоне Code::Blocks такой код:
Код:
#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif

#include <tchar.h>
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           _T("Code::Blocks ШАБЛОН ФРЕЙМА,       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Изображения
Тип файла: jpg codeblocks.jpg (113.4 Кб, 0 просмотров)
druidvic вне форума Ответить с цитированием
Старый 08.03.2023, 18:03   #2
Lapita12
Новичок
Джуниор
 
Регистрация: 08.03.2023
Сообщений: 24
По умолчанию

Добавьте следующий код в начало вашей программы:
Код:
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>

int main()
{
    // Установить кодировку входящих символов в консоли
    SetConsoleCP(1251);

    // Перекодировать стандартный поток ввода на utf-8
    _setmode(_fileno(stdin), _O_U8TEXT);

    // Перекодировать стандартный поток вывода на utf-8
    _setmode(_fileno(stdout), _O_U8TEXT);

    // Остальной код программы
    ...
}
Lapita12 вне форума Ответить с цитированием
Старый 09.03.2023, 02:23   #3
Пётр Седов
Форумчанин
 
Регистрация: 26.10.2022
Сообщений: 119
По умолчанию

druidvic, используйте Unicode-ные WinAPI-шные структуры и функции:
Код:
#define UNICODE
#include <windows.h>
Вы при этом потеряете поддержку старых Windows (Windows 95, Windows 98, Windows Me), но сейчас это уже мало кому нужно. В коде можно заменить:
TCHAR → WCHAR (16-битный элемент строки)
_T("abc") → L"abc" (строковый литерал, который в памяти программы будет храниться в кодировке UTF-16)
Цитата:
Сообщение от druidvic Посмотреть сообщение
В Виндовс - 1251
Эту кодировку лучше забыть. Сейчас подходит разве что для учебных заданий. Или для какой-то очень жёсткой экономии памяти.
Цитата:
Сообщение от druidvic Посмотреть сообщение
Код:
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
Тут надо единицу прибавлять к индексу:
Код:
wincl.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND + 1);
В MSDN же написано:
Цитата:
A color value must be one of the following standard system colors (the value 1 must be added to the chosen color).
Пётр Седов вне форума Ответить с цитированием
Старый 09.03.2023, 18:51   #4
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию

Спасибо что откликнулись.
Цитата:
Сообщение от Пётр Седов Посмотреть сообщение
Эту кодировку лучше забыть.
Пытаюсь, но вот на MSDN не скажу что очень понятно Особенно в машинном переводе.
Учиться приходится по старым примерам и книгам. Таких нюансов как THAR-WCHAR, L - _T и т.п. там просто нет. Нашел пока Conventions for Function Prototypes но этого очень мало.

Не сочтите за наглость дайте ссылку на спецификацию на С++ (оригинальную). А то в ссылках с
Яндекса и Гугла совсем запутался. Столько мусора .
druidvic вне форума Ответить с цитированием
Старый 09.03.2023, 19:36   #5
Пётр Седов
Форумчанин
 
Регистрация: 26.10.2022
Сообщений: 119
По умолчанию

druidvic, это у Microsoft издавна странный подход: все WinAPI-шные структуры и функции, работающие с текстом, сделаны в двух вариантах: A (ANSI) и W (wide). Разработчикам предлагалось писать код в обобщённом стиле:
Код:
const TCHAR* title = _T("abc");
SetWindowText(window_handle, title);
а потом делать 2 build-а:
1. Для линейки Windows 95/98/Me без макроса UNICODE:
TCHAR превращается в char, _T("abc") превращается в "abc"
Макрос SetWindowText превращается в SetWindowTextA, функция работает с текстом в ANSI-кодировке. Если Windows настроена на русский язык, то ANSI-кодировка -- это code page 1251.
2. Для линейки Windows NT/2000/XP/... с макросом UNICODE:
TCHAR превращается в WCHAR (16-битный), _T("abc") превращается в L"abc"
Макрос SetWindowText превращается в SetWindowTextW, функция работает с текстом в кодировке UTF-16.

Линейка Windows 95/98/Me закрыта, осталась только линейка Windows NT/2000/XP/..., она поддерживает и A-функции тоже, они реализованы как обёртки над W-функциями. Но лучше использовать W-функции, потому что Unicode.

В C++, WCHAR -- это то же самое, что wchar_t. Для работы с ним есть стандартные функции (wcslen) и классы (std::wstring). А TCHAR и макрос _T уже можно не использовать.
Пётр Седов вне форума Ответить с цитированием
Старый 10.03.2023, 14:07   #6
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию

Цитата:
Пётр Седов
Спасибо! Объяснение исчерпывающее.
Какой компилятор посоветуете? А то Code::Blocks 20.03, а GCC в нем - 1998 GNU C++. Староват вроде как уже.
druidvic вне форума Ответить с цитированием
Старый 10.03.2023, 14:23   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,706
По умолчанию

Цитата:
Сообщение от Пётр Седов Посмотреть сообщение
то у Microsoft издавна странный подход: все WinAPI-шные структуры и функции, работающие с текстом, сделаны в двух вариантах: A (ANSI) и W (wide).
В чем странность? Сначала были анси, потом ОС развивалась и появились юникод версии + совместимость. У вас есть не странный подход?
p51x вне форума Ответить с цитированием
Старый 10.03.2023, 14:43   #8
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Цитата:
Сообщение от druidvic Посмотреть сообщение
Староват вроде как уже.
В Settings - Compiler можно поставить галочку какому стандарту следовать (GNU/ISO, 98/11/14/17).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 10.03.2023, 21:26   #9
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию

BDA, пробовал.
Цитата:
||warning: command-line option '-std=c17' is valid for C/ObjC but not for C++|
Для С++ только 1998. Или GNU C++ или 1998 ISO C++ готовое workspace. Для других надо собирать руками.

Последний раз редактировалось druidvic; 10.03.2023 в 21:28.
druidvic вне форума Ответить с цитированием
Старый 10.03.2023, 21:49   #10
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

druidvic, ну не знаю, у меня в 20.03 доступны c++98, gnu++98, c++11, gnu++11, c++14, gnu++14.
Изображения
Тип файла: jpg flags.jpg (106.8 Кб, 1 просмотров)
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C# как сделать кодировку МКТ-2 Krasi Общие вопросы .NET 1 10.11.2015 11:17
Изменить кодировку из php Gefo PHP 2 27.02.2013 17:22
ie не меняет кодировку CodeNOT PHP 3 10.02.2012 03:22
Определить кодировку Shouldercannon PHP 1 31.07.2010 18:39
Про кодировку... Lich Работа с сетью в Delphi 5 29.12.2008 10:32