Выявление ошибки ввода целого числа
Модератор: Модераторы разделов
Выявление ошибки ввода целого числа
Скажите пожалуйста, как сделать проверку результата strtol. Нужно, чтобы не проходили слишком большие числа, дробные числа или абракадабра вроде "bhtrh/+^$". Проверку на длину я сделал: n1 == LONG_MAX, а вот как сделать проверку двух других условий -- не понял. Пробовал разные значения errno, но разобраться не смог. Помогите, пожалуйста!
P.S. Не по теме, но, может быть, кому-то не трудно ответить: как переместить курсор по экрану на 1 строку вверх?
P.S. Не по теме, но, может быть, кому-то не трудно ответить: как переместить курсор по экрану на 1 строку вверх?
Re: Выявление ошибки ввода целого числа
Может стоит попробовать регулярные выражения ?
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Roger Penrose,The Emperor's New Mind
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: Выявление ошибки ввода целого числа
из пушки по воробьям.
Вот так проще:
Код: Выделить всё
char *p = str;
while(*p >= '0' && *p <='9') p++;
if(*p)
//не число, или не целое число, в целом только цифры и ничего более
Re: Выявление ошибки ввода целого числа
Не стоит. Самому довольно сложно написать, а использовать стороннюю библиотеку ради такой крошечной проверки не стоит.
Нету проверки на переполнение, и почему знаки +- не учитываем?
_Gleb_, взгляни тут.
Я это только для винды помню
Re: Выявление ошибки ввода целого числа
Не нашёл, наверное, придётся небольшую логическую функцию написать.
Re: Выявление ошибки ввода целого числа
Не так уж и сложно
Код: Выделить всё
#include <stdio.h>
#include <pcreposix.h>
int main(int argc, char** argv)
{
char *str="1234568"; /* строка, в которой будет производится поиск */
char *pattern="(^\\d{,7}$)"; /* шаблон, по которому будет производится поиск */
//в фигурных скобках шаблона максимальное число символов в строке ,символы м.б. только цифрами
regmatch_t p[20]; /* массив, в который будут заноситься результаты поиска */
regex_t f; /* переменная, для хранения преобразованного шаблона */
int i,j;
if(regcomp(&f,pattern,0)) /* если возвращаемое значение не 0 - ошибка */
{
printf("Ошибка в шаблоне! %i\n",i);
exit(1);
}
if(regexec(&f,str,7,p,0)) /* если возвращаемое значение не 0 - значит ничего не найдено */
{
printf("Не найдено!\n");
exit(1);
}
printf("Найдено:\n");
return 0;
}
Код взят из примера, только шаблон изменил. Решение, которое предложил drBatty наверно самое подходящее
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Roger Penrose,The Emperor's New Mind
Re: Выявление ошибки ввода целого числа
drBatty писал(а): ↑23.12.2007 22:16Вот так проще:
Код: Выделить всё
char *p = str; while(*p >= '0' && *p <='9') p++; if(*p) //не число, или не целое число, в целом только цифры и ничего более
А что означает "if(*p)"?
Re: Выявление ошибки ввода целого числа
Так лишнюю библиотеку подключаем же все равно. Без нее вполне можно обойтись.
Не нашел, потому что там на английском? Попросил бы перевести. Вот перевод:
Код: Выделить всё
#define ERANGE 34
/* ... */
char str[] = "4233 ddsada";
char *end;
long int l = strtol(str, &end, 10);
if (*end != '\' || errno == ERANGE || *str == '\')
printf("Error!");
else
printf("%ld", l);
Поэтому я и пишу *p != '\'
Каждая строка завершается символом с кодом 0. Во время прохода строки мы перемещали указатель.
В конце концов мы либо обнаружили недопустимый символ, либо дошли до конца строки.
В этом условии мы именно это и проверяем, если мы не дошли до конца строки, то после разыменовывания получим
не 0, условие истинно, идем в if.
ЗЫ после \ съедается 0.
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: Выявление ошибки ввода целого числа
К этому надо привыкнуть, многие так пишут. Значит "если *p символ", считая что последний 0 - не символ. Часто встречается if(p) читается "если p валидный указатель"
проверка вроде уже сделана. Про знаки:
Код: Выделить всё
unsigned char *p = str;
Re: Выявление ошибки ввода целого числа
Вот не вижу я проверки на очень большие числа. Мы определили, является ли строка числом, это да.
Но еще нужно узнать, влезает ли это число в указанный тип.
Имхо, это не есть гуд. Код становится менее читабелен. Непонятно, что это - логическая переменная, число или указатель?
Но это уже дело вкуса.
Re: Выявление ошибки ввода целого числа
pryga
И вот из таких хаков критичные участки кода у меня только и состоят - на всю программу всего пара счетчиков, все остальные операции над указателями Это кусочек из моего поисковика.
Препод в универе, когда увидел вот такое в решении какой-то задачи изрек "б*я пи*дец"
Код:
/********************************************************************************
* *
* strnlowcpy_filter_wc() - filtruet <count> simvolov stroki <str>, *
* konvertiruya v rasshirennuyu stroku i pomeshyaet v <str_wc>. *
* *
********************************************************************************/
wchar_t *strnlowcpy_filter_wc(wchar_t *str_wc, const char *str, size_t count)
{
//////////////////////////////////////////
wchar_t *ptr_str_wc = str_wc; // Ukazatel na rasshirennuyu stroku
size_t str_offset = 0; // Smeshenie ukazatelya
mbstate_t mbstate; // Status sdviga
//////////////////////////////////////////
memset(&mbstate, 0, sizeof(mbstate));
for (; ((str_offset = mbrtowc(ptr_str_wc, str, sizeof(wchar_t), &mbstate)) > 0) && count;
++ptr_str_wc, str += str_offset, --count)
{
(*ptr_str_wc) = towlower(*ptr_str_wc);
if ( ptr_str_wc == str_wc ) continue;
if ( ((*(ptr_str_wc -1)) == L' ') && (*(ptr_str_wc) == L' ') )
{
(*(ptr_str_wc -1)) = L'\';
return str_wc;
}
}
str_wc[0] = L'\';
return NULL;
}
/********************************************************************************
* *
* strcmp_all_wc() - sravnenie dvuh rasshirennyh strok. *
* *
********************************************************************************/
int strcmp_all_wc(const wchar_t *str1_wc, const wchar_t *str2_wc)
{
for (; (*str1_wc) && (*str2_wc); str1_wc++, str2_wc++)
if ( (*str1_wc) != (*str2_wc) ) return 1;
if ( !(*str1_wc) && !(*str2_wc) ) return 0;
return 1;
}
Препод в универе, когда увидел вот такое в решении какой-то задачи изрек "б*я пи*дец"
Re: Выявление ошибки ввода целого числа
У меня тоже такое бывало. Особенно код смотрелся, когда там **, ***
Но преподы код не смотрели, к счастью И никаких указателей "я" на тип "б" не определяли
Но все-таки if (p != NULL) printf("ok"); смотрится лучше, чем if (p) printf("ok"),
при этом генерируется один ассемблерный код.
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: Выявление ошибки ввода целого числа
Вот тут я не знаю. Это довольно сложно сделать переносимым способом, разве что задействовать что-то из стандартной библиотеки. Не думаю, что это нужно. Если вам необходим конкретный диапазон - пожалуйста, проверяем на цифры, если ничего другого нет, то отрезаем ведущие нули, проверяем размер, и сравниваем.
Код: Выделить всё
while(*p++ == '0');
if(strlen(--p) == 3 && strcmp(p, "342") > 0 || strlen(p) > 3)
//не число
else
//число
Вы не правы. Попробуйте переписать код Liksys, будет менее понятнее. И насчёт одного кода вы так же не правы(в общем случае).
Не вижу здесь хаков. Только отступы побились по дороге...
Какая разница? р или не р, вот в чём вопрос. Когда я вижу такой код я знаю что это, если я напишу
if(eto_moj_ukazatel_ja_ego_sravnivaju_s_NULL)
мне не станет понятнее.
А если я пишу if(f = fopen("xx","w")), то я понимаю, что это проверка, есть файл или нет. Читается "Если файл открылся, то...", а не по вашему:
"Если я открываю файл и его поток не равен NULL, то..."
Re: Выявление ошибки ввода целого числа
drBatty писал(а): ↑24.12.2007 15:07Вот тут я не знаю. Это довольно сложно сделать переносимым способом, разве что задействовать что-то из стандартной библиотеки. Не думаю, что это нужно. Если вам необходим конкретный диапазон - пожалуйста, проверяем на цифры, если ничего другого нет, то отрезаем ведущие нули, проверяем размер, и сравниваем.
А чем не нравится способ, предложенный мною выше?
Ну это да, я же не могу это проверить во всех случаях на всех компиляторах
Все это субъективно. Так же как и то, где ставить { - на новой или на той же строке
- drBatty
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
- Контактная информация:
Re: Выявление ошибки ввода целого числа
Вы про stltol()? Нравится.
я не про то, я про несколько разные операторы.
if(p) преобразует p в int или в void*, а == к самому старшему типу(к примеру если есть char и long, char преобразуется в long)
Все это субъективно. Так же как и то, где ставить { - на новой или на той же строке
Да, я в некоторых случаях пишу if(p == NULL), если есть хоть малая вероятность, что я или компилятор поймёт не правильно. А насчёт скобок - главное выбрать стиль и затем его придерживаться. Вопрос религиозный, спорить не буду.