Как сравнивать символы в c

#c #linux #cstring #standard-library #c-strings

#c #linux #cstring #стандартная библиотека #c-строки

Вопрос:

У меня есть небольшой проект, который я делаю, который требует сравнения первого байта потока. Проблема в том, что этот байт может быть 0xe5 или любым другим непечатаемым символом и, таким образом, обозначать, что эти конкретные данные неверны (считывая их по 32 бита за раз). Допустимыми символами, которые я могу разрешить, являются A-Z, a-z, 0-9, ‘.’ и пробел.

Текущий код является:

 FILE* fileDescriptor; //assume this is already open and coming as an input to this function.
char entry[33];

if( fread(entry, sizeof(unsigned char), 32, fileDescriptor) != 32 )
{
    return -1; //error occured
}

entry[32] = '';  //set the array to be a "true" cstring.

int firstByte = (int)entry[0];

if( firstByte == 0 ){
    return -1;    //the entire 32 bit chunk is empty.
}

if( (firstByte amp; 0xe5) == 229 ){       //denotes deleted.
    return -1;    //denotes deleted.
}
  

Итак, проблема в том, что когда я попытался сделать следующее:

 if( firstByte >= 0 amp;amp; firstByte <= 31 ){ //NULL to space in decimal ascii
    return -1;
}

if( firstByte >= 33 amp;amp; firstByte <= 45 ){ // ! to - in decimal ascii
    return -1;
}

if( firstByte >= 58 amp;amp; firstByte <= 64 ) { // : to @ in decimal ascii
    return -1;
}

if( firstByte >= 91 amp;amp; firstByte <= 96 ) { // [ to ` in decimal ascii
    return -1;
}

if( firstByte >= 123 ){ // { and above in decimal ascii.
    return -1; 
}
  

это не работает. Я вижу символы, подобные тому, который обозначает черный шестигранный ромб с вопросительным знаком внутри него… Теоретически он должен был пропускать только следующие символы: Space (32), 0-9 (48-57), A-Z (65-90), a-z (97-122) , но я не знаю, почему это не работает должным образом.

Я даже пытался использовать функции в ctype.h -> iscntrl, isalnum, ispunct, но это также не сработало.

Сможет ли кто-нибудь помочь коллеге-новичку в c с тем, что, как я предполагаю, является простой проблемой c? Было бы весьма признателен!

Спасибо. Мартин

Комментарии:

1. Как вы вообще можете это видеть? Ваш код ничего не выводит.

2. Я добавил только фрагменты, которые выполняют обработку. Не выводится вывод. Во время отладки у меня был бы printf (» n% s n», запись); чтобы посмотреть, что произойдет после всех инструкций if, и я смог проверить, что выдается. Если бы какой-либо из операторов if сработал, не было бы никакого вывода, потому что возвращаемый 0 (логическое значение) прерывает функцию и существует. Код никогда бы не добрался до инструкции printf.

3. почему бы вам не использовать else if. Это сэкономит ваше время обработки. Кроме того, почему вы пишете ifs для символов, которые вы не хотите использовать. Я уверен, что символов, которые вы хотите использовать, меньше, и для них потребуется меньше инструкций

4. «else if» вряд ли сэкономит время обработки в любом оптимизирующем компиляторе. Тем не менее, это имеет больше смысла с точки зрения семантики / удобочитаемости.

Ответ №1:

Я не уверен, почему вы приводите его к int. Рассмотрите возможность использования одного из следующих:

 if ((entry[0] >= 'A' amp;amp; entry[0] <= 'Z') ||
    (entry[0] >= 'a' amp;amp; entry[0] <= 'z') ||
    entry[0] == ' ' || entry[0] == '.')
  

или

 #include <ctype.h>
if (isalnum(entry[0]) || entry[0] == ' ' || entry[0] == '.')
  

Комментарии:

1. Не используйте isalnum для этого, если вы не хотите, чтобы поведение зависело от локали. Например, isalnum(0xe5) может быть 0 или 1.

2. Я тоже не знаю, почему запрашивающий выполняет приведение; char это числовой тип.