Буквенно-цифровая проверка языка C на наличие неверных символов

#c #char #clang #undefined-behavior

#c #символ #лязг #не определено-поведение

Вопрос:

У меня этот код C полностью работает:

 #include <stdio.h>
#include <stdlib.h>
#include <ctype.h> 
#include <stdint.h>

int isAlphaNum(char *str) {
    for (int i = 0; str[i] != ''; i  )
        if (!isalnum(str[i]))
            return 0;
    return 1;
}

int main() {
    char *user_string = "abcdedf0123456789ABCD";
    if (isAlphaNum(user_string)) {
        printf(" is valid n");
    } else {
        printf(" is not valid n");
    }
    printf(" n end n");
    return 0;
}
 

из терминала копируется следующее:

но когда я получаю ввод через сокет, подобный этому:

 90a41ae8477a334ba609e06cujdikj#%amp;%$@$Dkdfsノ,ᅵハ"]￘モ {ᆳf
 

или

 ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒814
 

в этой части происходит сбой программы
:

 for (int i = 0; str[i] != ''; i  )
    if (!isalnum(str[i]))
 

Я использовал функцию от @chqrlie и работает:
отредактировано

 int isAlphaNum(const char *str) {
    //this message is printed , then craches
    printf("pass isAlphaNum userinput = %sn" , str);
    while (*str) {
        if (!isalnum((unsigned char)*str  ))
            return 0;
    }
    return 1;
}

if (isAlphaNum(userinput)) {
    printf(" success ;) n");
}
 

теперь все в порядке
, спасибо за помощь

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

1. как происходит сбой? какой-либо вывод ошибки предоставить? 🙂

2. Ваша программа, похоже, не принимает никаких входных данных. Можете ли вы поделиться тем, как вы принимаете входные данные и где происходит сбой?

3. Похоже, что у вас есть символы utf-8 (т.е. 0x80-0xFF). Иногда [в зависимости от реализации] ctype.h функции испытывают проблемы с этими значениями (например, они расширяют знак до отрицательных значений). Попробуйте: isalnum((unsigned char) str[i])

4. Предоставленные вами входные данные не соответствуют таблице ASCII, смотрите, как здесь определяется функция, chromium.googlesource.com/native_client/nacl-newlib / /мастер/…

5. Для меня это работает правильно. У вас есть двойная кавычка " в строке, которую вы хотите использовать, если вы просто жестко записываете ее в коде, вам нужно поставить перед ней обратную косую " черту, иначе она закроет строку, а остальные символы выдадут ошибку.

Ответ №1:

В вашем коде есть проблема, но она вряд ли вызовет проблему в системах GNU / linux, но может возникнуть в других: isalnum(str[i]) имеет неопределенное поведение, если str[i] имеет отрицательное значение, что возможно, если строка содержит 8-битные байты, а char тип подписан по умолчанию. isalnum() должны передаваться только значения типа unsigned char или специального отрицательного значения EOF .

Функция должна быть написана таким образом:

 #include <ctype.h> 

int isAlphaNum(const char *str) {
    while (*str) {
        if (!isalnum((unsigned char)*str  ))
            return 0;
    }
    return 1;
}
 

Ваше замечание о получении ввода через сокет заставляет меня подозревать, что вы не завершаете строку, полученную через сокет, нулем. Это может привести isAlphaNum() к чтению за пределами конца массива и вызвать ошибку сегментации, если до конца отображаемой области памяти нет нулевого байта (который раньше назывался сегментом в древних системах Multics).

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

1. спасибо за это исправление, все еще происходит сбой при этом: isalnum, с правильными и неправильными символами — как только программы попадают в isalnum(), происходит сбой в обоих случаях. я только что проверил это. я вызываю #include <ctype.h> в main, но я вижу, что это довольно странно

2. может быть, компиляция не добавляет: ctype.h?

3. Вы опубликовали фрагменты кода, это не помогает. Пожалуйста, опубликуйте полную программу, пытаясь удалить части, которые не вызывают проблемы, но сохраняя ее компилируемой и создавая проблему.

4. на самом деле это работает, ошибка была после этого кода. большое спасибо 🙂