2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 Ошибка expression (unsigned)(c+1) = 256
Сообщение19.11.2013, 21:31 
Добрый вечер, участники форума!
На этот раз передо мной задача написать небольшую записную книжку на Си.
В принципе я знаю, как писать, вот только в процессе уже напоролся на пару трудностей.
Вопрос первый: сам ввод происходит в формате Имя_Фамилия_Телефон
(_ - это пробел)и когда мы вводим из консоли эти данные для записи, как строчку, мы должны проверить соответствие
этому формату. Как это лучше всего реализовать? Понятно, что в строке два пробела. И дважды символ предшествует пробелу. Но ведь еще надо проверить, что бы в имени\фамилии были только буквы, а в телефоне - цифры. Вот здесь что-то не выходит. Ругается и выдает expression (unsigned)(c+1) <= 256. Объясните в чем дело, пожалуйста.

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <stdio.h>
#include <ctype.h>
#define BUFF 200

int deepcheck(char *str)
{
        while(*str!=' ')
        {
                if(isdigit(*str))
                        return 1;
            str++;
        }
        return 0;
}
int iscorrect(char *str) //Легкая проверка введенных данных(Имя/Фамилия)
{
 int spc=2; //счетчик пробелов
 int wdc=2; //слов
 while(*str)
 {
         if(*str == ' ')
             --spc;
         ++str;
         if(*str != ' ' && *(str+1) == ' ')
             --wdc;
 }
 if(spc)
         return 0;                    //Должно быть два пробела
 if(wdc)
         return 0;                    //Правильная последовательность
 if(deepcheck(str))
         return 0;
 return 1;                        //Формат выдержан
}

int main(void)
{
        FILE *MyBook;
    char *s = malloc(BUFF * sizeof(char));
        if((MyBook = fopen("MyBook.txt", "w")) == NULL)
        printf("Writing MyBook.txt error");
    /////////////////ВВОД В КОНСОЛЬ/////////////////
    printf("MyBook 1.0\nPlease, input data(Name_Surname_Telephone) \n");
        printf("English language is used(!) \n");
        ////////////////////////////////////////////////
        do{
    gets(s);                  //Получаем Имя/Фамилию
        if(!iscorrect(s))
        printf("Wrong input. \n");
        }while(!iscorrect(s));
    fputs(s, MyBook);
        fclose(MyBook);
        return 0;
}
 

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение19.11.2013, 21:57 
Где ругается? Обычно компиляторы пишут имя файла и номер строчки с ошибкой.

В принципе, я и так догадываюсь, что ошибка в вызове isdigit().
По стандарту аргумент этой фукции должен быть в диапазоне -1...255 - в точности диапазон значений функций getc()/getchar(). Соответственно, передавать в качестве аргумента значения типа char можно только если все символы - ASCII, т.е. из букв могут быть только латинские.
Проблема в том, что char может быть знаковым типом, и коды русских букв меньше нуля. Если же нужно проверять произвольные символы, их надо привести к нужному диапазону, например, как (*str&255), или кастом (unsigned char)*str.

Кстати, isdigit() будет работать и так, а вот чтобы работал isalpha()/islower()/isupper() надо выбрать правильную кодовую страницу.

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 00:30 

(Оффтоп)

Как же я все-таки "люблю" неявные преобразования в Си и совершенно неожиданные типы у аргументов функций стандартной библиотеки. Например, double и _Bool автоматически конвертируются друг в друга, а char*/signed char*/unsgined char* — нет. Прототипы вида int isalpha(int)/int isdigit(int)/etc. Тот факт, что реализациям разрешено делать char знаковым, хотя в стандарте при описании семантики явно отдается предпочтение unsigned char — в конце-концов, символьные литералы выглядят как беззнаковые числа: '\xFF', а не '\x-01' или '-\x01'. Уж про то, что (void*)0 не обязан равняться (void*)(1-1), я вообще не хочу вспоминать.

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 00:36 

(Оффтоп)

Joker_vD в сообщении #790579 писал(а):
Уж про то, что (void*)0 не обязан равняться (void*)(1-1), я вообще не хочу вспоминать.
А это-то почему?

С остальным согласен, хотя у всего есть причины. Не забывайте, что C - очень старый язык, и изначально предназначался для нозкоуровнего программирования с максимальным соответствием командам процессора (в то время - PDP-11).

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 00:48 

(Оффтоп)

Пардон, (void*)(1-1) будет равен нулевому указателю. Но, скажем,
  1. int i = 1; 
  2. void* p = (void*)(1-i); 
  3. void* q = (void*)0; 
  4. assert(p==q); 
может и упасть на ассерте — стандарт требует лишь чтобы преобразование константного целого выражения, равного 0, к void* давало константу нулевого указателя. А преобразование указателей и int'ов друг в друга полностью implementation-defined. Кстати, в Win32s в качестве нулевого указателя использовался указатель на адрес 0x400000.

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 14:06 
Нафига вообще учить студентов устаревшим языкам Си, Паскаль, и подобным? Современных что-ли мало?

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 15:06 

(2 Alexu007.)

C — не очень-то устаревший язык.

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 16:09 
Аватара пользователя
Alexu007, какие языки, по вашему мнению, современные?

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 16:14 
Ну есть вcякие C++, C#, Java, Qt

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 16:15 
Аватара пользователя
:facepalm:
Alexu007, чем вопить, что Си — старьё, то ли дело C++, молчите лучше в тряпочку, ей-богу, не смешите народ.

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 17:08 
Aritaborian в сообщении #790735 писал(а):
:facepalm:
Alexu007, чем вопить, что Си — старьё, то ли дело C++, молчите лучше в тряпочку, ей-богу, не смешите народ.

Да я собсна не воплю, но как бы Си современник MS-DOS, почему бы тогда и MS-DOSу не учить заодно?

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 17:16 
Aritaborian вам так попытался намекнуть, что использование C++ в противовес C в этом контексте бессмысленно, и лишь показывает вашу некомпетентность, т.к. C++ унаследовал практически все проблемы C.

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 17:53 
Аватара пользователя
Alexu007 в сообщении #790754 писал(а):
Да я собсна не воплю, но как бы Си современник MS-DOS, почему бы тогда и MS-DOSу не учить заодно?
:facepalm:
Это C++ - современник MS-DOS. С - современник PDP-11 и Unix.

Естественно, это все не считая того, что последние стандарты C и C++ вышли в 2011, и C11 значительно отличается от K&R C 70-x годов.

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 17:56 
Alexu007 в сообщении #790732 писал(а):
Qt

Разве это язык?

 
 
 
 Re: Ошибка expression (unsigned)(c+1) = 256
Сообщение20.11.2013, 18:31 
Аватара пользователя

(Оффтоп)

Надеюсь, после всего этого Alexu007 малость устыдится и перестанет направо и налево демонстрировать свою некомпетентность в различных областях знания :mrgreen:

 
 
 [ Сообщений: 19 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group