Мобильность и машинная зависимость программ. Проблемы с русскими буквами.
В современных UNIX-ах с поддержкой различных языков таблица ctype загружается из некоторых системных файлов - для каждого языка своя. Для какого языка - выбирается по содержимому переменной окружения LANG. Если переменная не задана - используется значение "C", английский язык. Загрузка таблиц должна происходить явно, вызовом
... #include <locale.h>
... main(){ setlocale(LC_ALL, ""); ... все остальное ... }
Вернемся к нашей любимой проблеме со знаковым битом у типа char.#include <stdio.h>
#include <locale.h>
#include <ctype.h>
int main(int ac, char *av[]){ char c; char *string = "абвгдежзиклмноп"; setlocale(LC_ALL, ""); for(;c = *string;string++){ #ifdef DEBUG printf("%c %d %d\n", *string, *string, c); #endif if(isprint(c)) printf("%c - печатный символ\n", c); } return 0; }
Эта программа неожиданно печатает
% a.out в - печатный символ з - печатный символ
И все. В чем дело???
Рассмотрим к примеру символ 'г'. Его код '\307'. В операторе
c = *string;
Символ c получает значение -57 (десятичное), которое ОТРИЦАТЕЛЬНО. В системном файле /usr/include/ctype.h макрос isprint определен так:
#define isprint(c) ((_ctype + 1)[c] & (_P|_U|_L|_N|_B))
И значение c используется в нашем случае как отрицательный индекс в массиве, ибо индекс приводится к типу int (signed). Откуда теперь извлекается значение флагов нам неизвестно; можно только с уверенностью сказать, что НЕ из массива _ctype.
Проблему решает либо использование
isprint(c & 0xFF) либо
isprint((unsigned char) c)
либо объявление в нашем примере
unsigned char c;
В первом случае мы явно приводим signed к unsigned битовой операцией, обнуляя лишние биты. Во втором и третьем - unsigned char расширяется в unsigned int, который останется положительным. Вероятно, второй путь предпочтительнее.
Итак, снова напомним, что русские буквы char, а не unsigned char дают отрицательные индексы в массиве.Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий