Mail.ruПочта0Мой Мир0ОдноклассникиВКонтактеИгры0ЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Разное описание setlocale. (Си)

kh fjkg Знаток (327), закрыт 3 года назад
Что значат эти 4 записи?
И какая из них правильная?
Если все 4 правильные, то что они все означают? Разные кодировки?
Я встречал в кодах все 4 написания.

setlocale(LC_ALL, "Russian");
setlocale(LC_ALL, "Russ");
setlocale(LC_ALL, "russ");
setlocale(LC_ALL, "rus");
Дополнен 3 года назад
setlocale(LC_ALL,"ru");
setlocale(LC_ALL,"ru_ru")
Лучший ответ
Alexandr Мудрец (11979) 3 года назад
setlocale(LC_ALL, "Russian");
serdПросветленный (20240) 3 года назад
В контексте вопроса вообще не важно чему равна LC_ALL.
Первый аргумент функции указывает категорию локали.
LC_ALL - вся локаль.
Второй аргумент - имя локали или NULL. Пустая строка ("") указывает на локаль по умолчанию.
kh fjkgЗнаток (327) 3 года назад
Проверьте букву 'я' с этим кодом:
Раскомментируйте по очереди 3 варианта setlocale
Разница есть
//setlocale(LC_ALL,"Russ");
//setlocale(LC_ALL,"Russian");
setlocale(LC_ALL,"Rus");
int name;
name=getwchar();
wprintf(L"%d\n", name);
kh fjkg, Есть еще одна подстава в этой функции. Если локаль указана неправильно то оно работает как дефолт. И тут начинаются приколы в винде. В винде если язык в системе англ - будет дефолтная английская. если русский - будет дефолтная русская. Т. е. когда наши соотечественники работают на "русской" винде - они могут написать хоть "Русский" и будет работать. Только пока они не попытаются запустить свой код на "англ." винде. Отсюда еще много неправильно написанных параметров.
kh fjkgЗнаток (327) 3 года назад
Так какой вариант правильный?
Всё таки "Russ" ?
Работают у меня эти варианты:
"Russ"
"ru"
"ru_ru"
В Вашем - при русской винде хоть "Русский" как параметр =) В Linux системах я использую LC_ALL, "ru-ru.UTF8" н-р. Что там у Вас в винде, когда в ней до сих пор 866 кодировка по умолчанию в консоли когда русский - смотрите сами. Я еще встречал такие записи .866 или .1251 проверять это на винде при различных языках не пробовал.
kh fjkgЗнаток (327) 3 года назад
>>Отсюда еще много неправильно написанных параметров.
В моём коде?
Это какие?
kh fjkgЗнаток (327) 3 года назад
Я поставил на инглиш винду. Сейчас это одним кликом в настройках делается.
kh fjkg, В Pro версии да. А вот Home - привед пользователям от Microsoft =)
kh fjkgЗнаток (327) 3 года назад
А официальную информацию где нибудь можно посмотреть по этому поводу?
kh fjkgЗнаток (327) 3 года назад
>>ru_ru =)
Что смешного?
Я этот пример сам выдумал, да, но на основе официального кода https://www.tutorialspoint.com/c_standard_library/c_function_setlocale.htm
Там написано "en_GB"
ru_RU смайл т. к. я сам опечатался и написал через - На сколько я помню параметр ОС зависим. Т. е. нет 100% стандарта на все ОС.
kh fjkgЗнаток (327) 3 года назад
Блин ещё _wsetlocale есть
kh fjkgЗнаток (327) 3 года назад
Возвращает однобайтовые коды на русские символы
_wsetlocale(LC_ALL, L"ru-RU");
int a;
a= getwchar();
wprintf(L"%ld\n", a);
kh fjkgЗнаток (327) 3 года назад
Так работает
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Rus");
wchar_t b=L'у';
int a;
a= getwchar();
wprintf(L"%ld\n%c %d\n", a, b,b);
kh fjkg, обычно setlocale используют для того, чтоб починить вывод русских букв. Но есть нюансы: - ввод всё равно не работает. - если выполнить SetConsoleCP(1251) и SetConsoleOutputCP(1251), то работает и без setlocale, и ввод и вывод. Но может не работать в Windows 7. - я не замечал, чтоб указанная строка влияла на вывод русских букв. Можно написать так: setlocale(LC_ALL, "") - в современной программе должна использоваться кодировка Unicode. Для Windows родная кодировка UTF-16. Всё, что работает с символами ANSI - всё плохо (возможно, кроме ввода-вывода в файл)
kh fjkgЗнаток (327) 3 года назад
setlocale(LC_ALL, "Russian"); распознаёт сохранённые символы wchar_t f=L'я';

А a= getwchar(); возвращает у меня странные коды символов, поэтому setlocale не может правильно это распознать.
Для того чтоб getwchar возвращало правильные однобайтные коды, я сначал пишу это
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
Потом все однобайтные символы этим setlocale(LC_ALL, "Russian"); перевожу в широкие символы

Получается здесь a= getwchar(); и здесь wchar_t f=L'я'; одинаковый код
Остальные ответы
Евгений Высочин Просветленный (38033) 3 года назад
Русская локаль
В Винде - setlocale(LC_ALL, "Russian");
В Андроид, Дебиан - setlocale(LC_ALL, "Russian");
В Федоре - setlocale(LC_ALL, " ");
kh fjkgЗнаток (327) 3 года назад
setlocale(LC_ALL, " "); Пустые скобки означают что надо использовать ту локаль, которая имеет Операционная система.
Евгений Высочин Просветленный (38033) kh fjkg, пустые скобки потому, что в системе полноценно используется кодировка UTF-8, и древняя Си-шная функция setlocale в принципе не нужна. Но если при этом в программе используются широкие символы wchar, то кириллица не будет отображаться в консоли без предварительного запуска setlocale. Поэтому приходится писать хотя-бы setlocale(LC_ALL, "");
kh fjkgЗнаток (327) 3 года назад
Почему getwchar при этой конструкции
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
возвращает двухбайтные символы?
Если убрать или это
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
или это setlocale(LC_ALL, "Russian");
то getwchar возвращает или случайные значения или однобайтную кодировку.
Полный код так выглядит
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
wchar_t b=L'я';
int a;
a= getwchar();
wprintf(L"%ld\n%c %d\n", a, b,b);
Евгений Высочин Просветленный (38033) kh fjkg, в Винде для отображения кириллицы лучше использовать стандартную связку из библиотек locale.h, wchar.h, а в коде писать setlocale для символов wchar. Всё, больше ничего добавлять не надо. И должно всё правильно работать, даже на WindowsXP. Потому что это древние стандартные библиотеки и функции Си, давно испытанные.
Евгений ВысочинПросветленный (38033) 3 года назад
SetConsoleCP это нестандартная функция Майкрософт. Её не нужно смешивать с setlocale. Сама setlocale написана только для использования символов wchar, и больше ни для чего другого. А SetConsole наверное больше подойдет для отображения двухбайтовых char-символов, как попытка реализовать кодировку utf-8. Это моё мнение. Но я давно не работаю в Windows, поэтому не в курсе, что там с новшествами Майкрософт.
kh fjkgЗнаток (327) 3 года назад
Это факт что правильно не работает по отдельности
Попробуйте например так
setlocale(LC_ALL, "Russian");
int a;
a= getwchar();
wprintf(L"%c %d\n", a,a);
Во первых возвращает однобайтную кодировку, во вторых не отображает символы.
kh fjkgЗнаток (327) 3 года назад
setlocale(LC_ALL, "Russian"); распознаёт сохранённые символы wchar_t f=L'я';

А a= getwchar(); возвращает у меня странные коды символов, поэтому setlocale не может правильно это распознать.
Для того чтоб getwchar возвращало правильные однобайтные коды, я сначал пишу это
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
Потом все однобайтные символы этим setlocale(LC_ALL, "Russian"); перевожу в широкие символы

Получается здесь a= getwchar(); и здесь wchar_t f=L'я'; одинаковый код
Евгений Высочин Просветленный (38033) kh fjkg, нудно использовать не getwchar, а wscanf.
kh fjkgЗнаток (327) 3 года назад
Вы ведь на линуксе работаете?
Я думаю у вас это
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
выставлено по дефолту.
Потому что мне надо вводить это
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
чтоб потом это setlocale(LC_ALL, "Russian");
могло распознать что вернул wscanf

Те же самые неправильные коды возвращает wscanf без этого
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
Евгений Высочин Просветленный (38033) kh fjkg, я пробовал как-то на виртуалке, ставил в виртуалбокс винду XP, 7 и 10. Там все мои примеры работают без всякого SetConsole
kh fjkgЗнаток (327) 3 года назад
Да, я видел.
%lc- Long Char
%ls-Long String
kh fjkgЗнаток (327) 3 года назад
Что означает эта большая буква L, которую перед ковычками ставят? wscanf(L""
Аббревеатура
Евгений Высочин Просветленный (38033) kh fjkg, большая буква L это экранирование ввода-вывода для широких строк и символов. Она тоже обязательна.
kh fjkgЗнаток (327) 3 года назад
Да я давно ей пользуюсь, просто не знаю что она означает. Перевод что ли
kh fjkgЗнаток (327) 3 года назад
А код не работает это точно.
Я выше думаю хорошо описал логику. 44 минуты назад
Евгений Высочин Просветленный (38033) kh fjkg, нужно просто быть очень внимательным, особенно с языком Си. Одна неверная буква в коде - и всё, код не работает. Все заморочки в основном от мелких ошибок, от невнимательности. Особенно если привык работать только в Винде. В Винде приучают писать код как попало, с использованием нестандартных функций и библиотек, которые в стандарте не используются. Когда начнёшь писать в другой ОС, то по началу вообще никакой код не будет работать.)) У меня такое было. Но потом стал читать стандарт, писать чисто на стандарте, и всё заработало.
kh fjkgЗнаток (327) 3 года назад
Дело не в этом. Вы не учитываете то какая у меня сейчас кодировка. Я и сам то не знаю какая она.
А это
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
просто ставит корректную кодировку для кириллицы.

Кстати можно ли через код узнать какая у меня кодировка? Не сравнивая коды символов)
Евгений Высочин Просветленный (38033) kh fjkg, чтобы быстро узнать свою кодировку, выведи все настройки окружения консоли. Сколько их по дефолту в Винде не знаю, но можно в качестве эксперимента сделать так: #include <stdio.h> int main(int argc, char *argv[]) { for(int i = 0; i < 15; i++) printf("\n %s", argv[i]); return 0; } Если выдаст ошибку, то уменьш границу цикла, скажем, вместо 15 напиши i < 10. В числе выведенных настроек будет и нужная - LANG
kh fjkgЗнаток (327) 3 года назад
Уменьшал до одного.
\build-untitled4-Desktop_Qt_6_1_3_MinGW_64_bit-Release\release\untitled4.exe
(null)
Евгений Высочин Просветленный (38033) kh fjkg, тогда пробуй так: #include<stdio.h> #include<locale.h> int main() { char *loc = setlocale(LC_CTYPE, NULL); printf("\n my locale = %s", loc); system("pause");//для винды пауза return 0; }
kh fjkgЗнаток (327) 3 года назад
Процесс висит, конечной фразы нет: Нажните любую кнопку для выхода
kh fjkgЗнаток (327) 3 года назад
А, вот появилась эта фраза. Очень долго просто ждало. Это не из за компа
kh fjkgЗнаток (327) 3 года назад
my locale = C
Что это значит?
Евгений Высочин Просветленный (38033) kh fjkg, замени в setlocal LC_CTYPE на LC_ALL: char *loc = setlocale(LC_ALL, NULL); Снова попробуй вывести значение локали.
kh fjkgЗнаток (327) 3 года назад
То же самое:
my locale = C
Если включаю setlocale(LC_ALL, "Russian");
то выдаёт my locale = Russian_Russia.1251

Если включаю это
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
то ничего не меняется
my locale = C
kh fjkgЗнаток (327) 3 года назад
Пишут что С это формат типа как ASCII, UTF но этот формат не для людей, а для компьютера
https://unix.stackexchange.com/questions/87745/what-does-lc-all-c-do
kh fjkgЗнаток (327) 3 года назад
Я всё написал, вывел всё
Евгений Высочин Просветленный (38033) kh fjkg, другое и не будет показывать. У меня на Андроид пишет C.UTF-8
kh fjkgЗнаток (327) 3 года назад
У меня только С пишет. Ничего больше нет
Евгений Высочин Просветленный (38033) kh fjkg, без разницы что он пишет. Главное - правильно использовать стандартные функции. Если что не так, кидай скрин своего исходного текста программы в среде разработки. Может там тупо нужно поменять кодировку текстового редактора на utf-8, если в консоли не отображает кириллицу.
kh fjkgЗнаток (327) 3 года назад
В этом и проблема видно была.
Кодировка у меня какая то стандартная машинная.
Евгений Высочин Просветленный (38033) kh fjkg, поменяй кодировку своего текстового редактора, в котором пишешь программу, на utf-8. После этого весь русский текст будет отобрадать в редакторе всякие кракозябры. Поэтому заново перепиши русский текст.
Похожие вопросы