Страницы

Поиск по вопросам

Показаны сообщения с ярлыком ascii. Показать все сообщения
Показаны сообщения с ярлыком ascii. Показать все сообщения

среда, 5 февраля 2020 г.

Java ASCII и (char)

#java #ascii


Вводил разные значения в 

 System.out.println((char)855);


и сверял полученный результат с таблицей ASCII. Результаты сходились только до 127.
Почему дальше результаты не сходились? (ведь таблицу расширили до 256) И почему можно
вообще использовать такие значения как 855?
    


Ответы

Ответ 1



Дело в том, что в Java строки представляются в стандарте Unicode. Поэтому множество представимых символов не ограничено таблицей ASCII. Можете здесь посмотреть таблицу Unicode. Тип char в Java 2-х байтовый, т.е. в нём представимы числа от 0 до 65535, с помощью которых представляются символы в кодировке UTF-16. Символом с кодом 855 является Комбинируемый надстрочный правый полукруг. Собственно, он и выводится у вас в программе.

среда, 1 января 2020 г.

Как рисовать сиволами псевдографики в консоли linux СИ

#linux #c #gcc #консоль #ascii


вот на винде такую штуку делал (обычные символы Ascii кода)

а в линуксе псевдографики вообще нет чтоли?
написал такую вот фигню, и вместо знаков ромбы с вопросами

#include 

void main()
{
    for(int y = 0; y < 32; y++)
    {
        for(int x = 0; x < 64; x++)
        {
            printf("%c", 177);
        }
    }
}

    


Ответы

Ответ 1



#include #include int main() { // установить локаль, необходимо сделать дабы стандартные библиотеки знали, // в какую кодировку преобразовывать длинные символы при выводе setlocale (LC_ALL, ""); // основной способ, должен быть переносимым и корректно работать // при компиляции под любую систему (стандартным компилятором C99 или C11) // в локали который есть псевдографика printf("%lc", L'▒'); // строго говоря, немного менее переносимый способ, привязанный к UNICODE printf("%lc", 0x2592); // не лучший способ, будет работать только если 8-битная кодировка файла совпадает // с кодировкой локали (на большинстве современных систем и то и другое — utf-8). printf("▒"); return 0; } Также можно работать напрямую с широко-символьными потоками ввода-вывода: #include #include #include int main() { setlocale (LC_ALL, ""); putwchar(L'▒'); putwchar(0x2592); fputws(L"▒", stdout) return 0; }

Ответ 2



Проще всего найти нужные символы в таблице Unicode и выводить их в кодировке utf-8. avp@avp-ubu1:hashcode$ cat t-utf.c && gcc t-utf.c && ./a.out #include int main (int ac, char *av[]) { // Коды мастей в Unicode: 0x2660 ... 0x2667 // 0010 0110 0110 0000 // 0010011001100000 // группируем биты по 6 для перевода в utf-8: 0010 011001 100000 // utf-8: 11100010 10011001 10100000 0xe2 0x99 0xa0 char *cardsuit[8] = {"\xe2\x99\xa0", // 0x2660 "\xe2\x99\xa1", "\xe2\x99\xa2", "\xe2\x99\xa3", "\xe2\x99\xa4", "\xe2\x99\xa5", "\xe2\x99\xa6", "\xe2\x99\xa7" // 0x2667 }; puts("https://unicode-table.com/ru/#geometric-shapes"); printf("карточные масти: "); for (int i = 0; i < 8; i++) printf("%s", cardsuit[i]); return puts("") == EOF; } https://unicode-table.com/ru/#geometric-shapes карточные масти: ♠♡♢♣♤♥♦♧ avp@avp-ubu1:hashcode$ Кстати, если есть какие-то проблемы с локалью (или вообще с wctomb), то для кодирования символов Unicode с помощью UTF-8 можно использовать вот такую функцию: // returns utf-8 length (max 4) or 0 if error in ucs // see https://unicode-table.com/en/ int ucs_to_utf8 (unsigned int ucs, char *utf) { if (ucs < 128) { utf[0] = ucs; // ascii return 1; } int l; if (ucs < (1 << 11)) { // 0x80 .. 0x7ff "Latin-1 Supplement" ... cyrillic ... NKo (africa) // 110 xxxxx 10xxxxxx l = 1; utf[0] = (ucs >> 6) | 0xc0; } else if (ucs < (1 << 16)) { // 0x800 ... 0xffff Samaritan ... CJK ... Specials // 1110 xxxx 10xxxxxx 10xxxxxx l = 2; utf[0] = (ucs >> 12) | 0xe0; utf[1] = ((ucs >> 6) & 0x3f) | 0x80; } else if (ucs > 0xe01ef) // not defined yet return 0; else { // 0x10000 ... 0xe01ef "Linear B Syllabary" ... "CJK Compatibility Ideographs Supplement" ... // 11110 0xx 10xxxxxx 10xxxxxx 10xxxxxx l = 3; utf[0] = (ucs >> 18) | 0xf0; utf[1] = ((ucs >> 12) & 0x3f) | 0x80; utf[2] = ((ucs >> 6) & 0x3f) | 0x80; } utf[l] = (ucs & 0x3f) | 0x80; // low 6 bits return ++l; }

Ответ 3



Одно из решений - включить в консоли совместимость с кодировкой CP866 Терминал ubuntu это позволяет, собственно это я и сделал Правда это далеко не смое лучшее решение, т.к. в некторых случаях консоль теперь показывает откровенную дич

четверг, 19 декабря 2019 г.

как конвертировать int в 16 ричную систему?

#java #ascii


Добрый день нужно на сервер отправлять данные ф формате 16 речной системы ASCII.К
примеру -1 как FFFFFFFF соответсвенно -2 как FFFFFFFE

что это за fff-ки?как конверитровать int a =-1 в   FFFFFFFF?

Спасибо за внимание
    


Ответы

Ответ 1



Данный вид записи называется дополнительный код. В Java можно получить такую запись стандартными средствами: Integer.toHexString(1); // 1 Integer.toHexString(2); // 2 Integer.toHexString(-1); // ffffffff Integer.toHexString(-2); // fffffffe Если нужно запись положительных чисел дополнить слева нулями до 8 символов, поможет String.format(): String.format("%8s", Integer.toHexString(123)).replace(' ', '0') // 0000007b

Ответ 2



Самый простой способ int a =-1; System.out.println(Integer.toHexString(a));

Ответ 3



В java так String input = ... // my UTF-16 string StringBuilder sb = new StringBuilder(input.length()); for (int i = 0; i < input.length(); i++) { char ch = input.charAt(i); if (ch <= 0xFF) { sb.append(ch); } } byte[] ascii = sb.toString().getBytes("ISO-8859-1"); // aka LATIN-1

среда, 18 декабря 2019 г.

Таблица ASCII и её соответствие в c++

#cpp #ascii


Почему в таблице ASCII российская буква 'a' равна 160, а когда я пишу: 

int a = 'а';

cout << a << endl;


мне выводит -32?
    


Ответы

Ответ 1



Результат выполнения Вашего кода зависит от нескольких факторов. В частности от кодировки исходника, используемого компилятора и правил кодирования символьных и строковых литералов. Например, возможен вариант вывода числа 53424 и предупреждения: multi-character character constant [-Wmultichar] при использовании UTF-8 кодировки исходника и компилятора gcc. Т.о. 'а' это вовсе и не символ, а целое число (более подробно о мультисимвольных литералах можно почитать тут), в чем можно убедиться проверкой sizeof, которая вернет такое же значение, как и для int, а не для char (по определению 1). При использовании clang вообще получим ошибку компиляции: character too large for enclosing character literal type Чтобы избавиться от такой ошибки придется изменить тип символьного литерала (например на wchar_t, задав префикс L). В этом случае на выводе получим уже другое число: 1072, что соответствует UTF-16 коду русской буквы а. Чтобы получить такой же результат как у Вас, но с помощью онлайн-компилятора gcc можно использовать ключ -fexec-charset с кодовой страницей 1251. При этом, хочу заметить, что для буквы а код 160 (0xA0) соответствует кодировке cp866, а не cp1251, в которой он равен 224 (0xE0). Поэтому -32 в 160 превратиться не сможет путем обычного преобразования знакового числа в беззнаковое. Если уж очень хочется получить на выводе именно 160 помимо преобразования в беззнаковый тип надо ещё использовать кодовую страницу cp866. Т.е. собирать следующий код с ключом -fexec-charset=cp866: #include int main() { int a = static_cast('а'); std::cout << a << std::endl; }

Ответ 2



Потому что число больше 127 не влезает в знаковый char, у которого диапазон от -128 до 127. Зато влезает в беззнаковый, но, судя по всему, на вашей системе char является знаковым, поэтому происходит конвертация из знакового char в знаковый int. Т.к. любое число char всегда влазит в int, то получается, что в int попадает отрицательное число из char Чтобы получить положительное число, просто используйте любой unsigned тип в качестве приёмника значения, а исходный char преобразуйте к unsigned char: unsigned int a = static_cast('а');

суббота, 7 декабря 2019 г.

Что есть ANSI и ASCII

#c #utf_8 #ascii #ansi


Я бы хотел, наконец, разобраться, как правильно называть строки 8-ми битных символов.

Что такое строка символов UTF-8 мне хорошо понятно - это строка, каждый символ которой
представлен переменным количеством 8-ми битных блоков (байтов).

Что такое строки UTF-16/UTF-32 мне тоже ясно.

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

Кто-то их называет ascii, кто-то ansi, или просто CP1251, если подразумевается конкретная
кодировка.

Помогите разобраться. Гугл только запутал.
    


Ответы

Ответ 1



ASCII (American Standard Code for Information Interchange) - первый вариант кодировки. Потом появились CP866, KOI8-R, Windows 1251 и вот это всё. Так что, CP1251 - это расширенная версия ASCII. ANSI - это расширения ASCII, в которых были удалены псевдографические элементы и добавлены символы типографики. CP1251 - это пример ANSI кодировки. Если на диаграмме Эйлера показать:

Ответ 2



ASCII (читается аски́) - это первая кодировка применявшаяся еще в пору когда 99% юзеров SO еще даже не родились (1963 год). Кодировка 7-битная, то есть определено 128 символов, 8-й бит полного байта использовался для проверки четности поскольку в то время каналы были ненадежные, то предполагалось что будет проверяться каждый полученный байт. Далее со временем стало понятно, что для других языков можно использовать 8-й бит для отображения национальных символов - то есть использовать 256 символов. Эту расширенную 8-битовую кодировку условно называют ANSI (читается анси́) по названию американского института стандартов в рамках которого и была предложена 8-битовая кодировка. Соответственно, для каждого национального языка была предложена своя раскладка второй половины таблицы (от 128 до 255 символа), а первая половина таблицы от 0 до 127 - изначальные символы ASCII. KOI-8, CP-1251, 1252 и проч. - это различные инкарнации ANSI Далее когда дело дошло до иероглифов стало понятно, что в 256 символов не уместиться и появилась UNICODE (читается юникод) - где на 1 символ отводится 2 байта, то есть 65536 символов, где таблица была жестко поделена между национальными символами, например таблица ASCII осталась в интервале U+0000 до U+007F, а наша с вами кириллица в интервале U+A640 до U+A69F ну и т.д. С нарастанием угара стало ясно что 65536 символов также не хватает, потому что появились эмодзи, стали поднимать голову другие национальные символы справедливо указывавшие на нехватку места в таблице UNICODE, тогда был предложен UTF-8 (читается ютиэф 8), где количество байтов в символе имеет разную длину и может быть от 1-го до 4 байт, что дает 1 112 064 символов. Вот, как то так.

Ответ 3



Считаю название «восьмибитные» или «однобайтовые кодировки» вполне корректным общим названием для подобных вещей. Само собой, если подразумевается какая-то конкретная кодовая страница/кодировка, то она и указывается: «KOI8-R», «CP1251» «CP1250», «ISO8859-5». ASCII как стандарт (а это действительно стандарт — American standard code for information interchange) определяет, если я правильно помню, только первые 127 кодов символов. Поэтому формально символы типа «я», «č», «њ», «Ḱ» не принадлежат ASCII. «ANSI» — это вообще исключительно русскоязычный (sic!) термин для CP1251, т.к. вообще-то это сокращение обозначает американский национальный институт стандартизации (а «OEM» — original equipment manufacturer).

среда, 12 июня 2019 г.

Строка не содержит управляющих ASCII символов

Есть строка, в которой есть цифры, буквы и знаки препинания. Например: г. Москва, ул. Ленина д.5. Надо проверить, есть ли в ней символы, относящиеся к управляющим символам ASCII таблицы(коды с 0х00 до 0х1F и 0x7F).
Вообще не могу понять как в моей строке искать эти символы. Не перечислять же мне их вручную, а потом посимвольно сравнивать...


Ответ

Надо проверить, есть ли в ней символы, относящиеся к управляющим символам ASCII таблицы(коды с 0х00 до 0х1F).
Char.IsControl тут не подойдёт, так как этот метод проверяет также наличие управляющих символов всей таблицы Юникода.
Нужно использовать LINQ. s.Any(c => (c >= 0 && c <= 31) || c == 127) проверит наличие требуемых символов в тексте, а s.Where(c => (c >= 0 && c <= 31) || c == 127).ToList() вернёт их список:
var s = "\x08

"; var result = s.Any(c => (c >= 0 && c <= 31) || c == 127); Console.WriteLine(result); // => True var result2 = s.Where(c => (c >= 0 && c <= 31) || c == 127).ToList(); Console.WriteLine("'{0}'", string.Join("';'", result2));
Result:
True '';' ';' ';' '
См. демо
Можно и регулярным выражением:
var hasAsciiControlChr = Regex.IsMatch(s, @"[\u0000-\u001F\u007F]");
См. C#-демо

Почему перевод строки это CR+LF а не LF+CR?

Ведь по идее сначала происходит подача новой строки, а уже потом возврат каретки https://youtu.be/oxN1C2QQUIE
PS Пользователям macOS и linux: у вас реально только один символ LF?


Ответ

Википедия объясняет это так: при печати на телетайпе возврат каретки длился больше, чем печатается один символ. Поэтому если сначала перевести строку, а потом вернуть каретку и печатать дальше, то первый символ печатался где-нибудь в середине строки.
Порядок CR, LF был выбран, чтобы дать каретке небольшую фору. Даже её могло быть недостаточно, и тогда после отправлялась некоторая пустая последовательность.
только один символ LF
Начал использоваться в ОС Multics, где перевод каретки принтера (и, по всей видимости, ожидание до конца перевода) осуществлялся его драйвером. CR без новой строки можно было использовать для разных декоративных эффектов. Из Multics LF перешел в Unix, а оттуда в остальные ОС.

среда, 31 октября 2018 г.

как конвертировать int в 16 ричную систему?

Добрый день нужно на сервер отправлять данные ф формате 16 речной системы ASCII.К примеру -1 как FFFFFFFF соответсвенно -2 как FFFFFFFE
что это за fff-ки?как конверитровать int a =-1 в FFFFFFFF?
Спасибо за внимание


Ответ

Данный вид записи называется дополнительный код. В Java можно получить такую запись стандартными средствами:
Integer.toHexString(1); // 1 Integer.toHexString(2); // 2 Integer.toHexString(-1); // ffffffff Integer.toHexString(-2); // fffffffe
Если нужно запись положительных чисел дополнить слева нулями до 8 символов, поможет String.format()
String.format("%8s", Integer.toHexString(123)).replace(' ', '0') // 0000007b