Стандарт C говорит, что символьные константы, такие как 'ç', являются целочисленными константами:
§6.4.4.4 / 9
Целочисленная символьная константа имеет тип int.Значение целочисленной символьной константы, содержащей один символ, который отображается на однобайтовый исполнительный символ, является числовым значением представления сопоставленного символа, интерпретируемого как целое число.
Если тип символа равенподписанный на вашем компьютере (это в Linux), тогда, когда comando
содержит 'ç' и повышен до целого числа, он становится отрицательным целым числом, тогда как 'ç' является положительным целым числом.Отсюда и предупреждение от компилятора.
Для 8-битного набора символов, безусловно, самый быстрый способ сделать такую операцию - создать таблицу из 256 байтов, где каждая позиция содержит версию без акцентасимвола.
int unaccented(int c)
{
static const char map[256] =
{
'\x00', '\x01', ...
...
'0', '1', '2', ...
...
'A', 'B', 'C', ...
...
'a', 'b', 'c', ...
...
'A', 'A', 'A', ... // 0xC0 onwards...
...
'a', 'a', 'a', ... // 0xE0 onwards...
...
};
if (c < 0 || c > 255)
return EOF;
else
return map[c];
}
Конечно, вы бы написали программу - возможно, скрипт - для генерации таблицы данных, а не делали это вручную.В диапазоне 0..127 символ в позиции x является символом с кодом x (т. Е. map['A'] == 'A'
).
Если вам разрешено использовать C99, вы можете улучшить таблицу, используя назначенные инициализаторы:
static const char map[] =
{
['\x00'] = '\x00', ...
['A'] = 'A', ...
['a'] = 'a', ...
['å'] = 'a', ...
['Å'] = 'A', ...
['ÿ'] = 'y', ...
};
Не совсем понятно, что вы должны делать с дифтонгами буквами, такими как 'æ' или 'ß', которые не имеют эквивалента ASCII;однако простое правило «когда сомневаешься, не меняй его» можно применять разумно.Это не акцентированные символы, но и не символы ASCII.
Это не очень хорошо работает для UTF-8.Для этого вам нужны более специализированные таблицы, основанные на данных в стандарте Unicode .
Также обратите внимание, что перед вызовом этого вы должны привести любое значение 'char' к 'unsigned char'.Тем не менее, кодекс может также попытаться справиться с нарушителями.Однако трудно отличить «ÿ» (0xFF) от EOF, когда люди неосторожны при вызове функции.Стандартные символьные тестовые макросы C должны поддерживать все допустимые символьные значения (при преобразовании в unsigned char) и EOF в качестве входных данных - это соответствует этой схеме.
§7.4 / 1
Во всех случаях аргументом является int, значение которого должно быть представлено как беззнаковый символ или должно равняться значению макроса EOF.Если аргумент имеет любое другое значение, поведение не определено.