Программирование на СИ. ( в чём ошибка? )

Тема в разделе "WASM.BEGINNERS", создана пользователем stellaco, 24 май 2009.

  1. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Всем большое спасибо за помощь !!!
     
  2. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Вот снова столкнулся с проблемой.
    Часа 4 убил на поиск ошибки.

    Цель весьма проста, открыть дескриптор файла.
    В первом цикле while считать построчно содержимое файла в буфер BUFF.
    Просканировать буфер BUFF на наличие символа "#" и в том случаи если он найден, то проверить следующий символ (ALPHANUMERIC). И если следующий символ, не один из списка ALPHANUMERIC , вывести "Ошибка". В случаи, если текст соответствует к примеру #asfhgdfhgfhfdh #Agfgsd #Bdf , увеличить count на еденицу.


    Вот код.

    Код (Text):
    1. #define ALPHANUMERIC ( A || a || B || b || C || c || 1 || 2 || 3 )
    2.  
    3. int main() {
    4. char BUFF[system_conf.page_size];
    5. char *symbol_ptr = BUFF;
    6. char current_symbol;
    7. int count = 0; // количество совпадений
    8.  
    9. /* функция fgets читает построчно файл в буфер BUFF  */
    10. while( fgets( BUFF, system_conf.page_size, fdopen_ptr ) != NULL)  // берём строку из файла(fdopen_ptr)
    11. {
    12. printf("Начинается первый цикл while \n");
    13. symbol_ptr = BUFF; // установили указатель на начало буфера
    14. printf("Указатель на buff установлен \n");
    15.  
    16. printf("Начинается второй цикл while \n");
    17. while(current_symbol= *symbol_ptr++)
    18. {
    19. printf("current_symbol = %c \n  ", (char*)current_symbol);
    20. //до этого места ошибки нет
    21.  
    22. // а тут  начало ошибки....
    23. if( (char*)current_symbol == "#" )  // МНЕ НУЖНО СРАВНИТЬ ТЕКУЩИЙ СИМВОЛ С "#"
    24.  {
    25.   printf("Внутри ошибочки");
    26.   symbol_ptr++ ; // проверяем, символ после #
    27.   if ( *symbol_ptr != ALPHANUMERIC ) // если символ следующий за # не ALPHANUMERIC
    28.   printf("Ошибка");
    29.   count++; // если всё верно, то count++
    30.   *symbol_ptr--;
    31.  }
    32. } // второй цикл while
    33. } // первый while
    34.  
    35. printf("Конец");
    36. return 0;
    37. }
    программа читает файл fdopen_ptr, содержащий следующий текст
    Код (Text):
    1. aaaaa #ggg
    2. bbbbb #ddd
    3. cc#cc pp#p
    4. ddddd kkk#
    Вот вывод компилятора:

    Как видно из вывода программы, управление не передаётся в блок по условию
    if( (char*)current_symbol == "#" ) // МНЕ НУЖНО СРАВНИТЬ ТЕКУЩИЙ СИМВОЛ С "#"
    {
    printf("Внутри ошибочки");
    symbol_ptr++ ; // проверяем, символ после #
    if ( *symbol_ptr != ALPHANUMERIC ) // если символ следующий за # не ALPHANUMERIC
    printf("Ошибка");

    *symbol_ptr--;
    }


    Что за косяк у меня снова в коде?? ( 100 пудово ошибка в if( (char*)current_symbol == "#" ) )..никак не могу исправить ошибку (((
     
  3. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    stellaco
    и здесь тоже :)
    наверное имелось ввиду:
    Код (Text):
    1. if(current_symbol == '#')
    ?
    а еще:
    Это ваще на каком языке? Не на С так точно :)
     
  4. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    При изменении if( (char*)current_symbol == "#" ) на if(current_symbol == '#')
    Компилятор выдаёт ошибку ( в этой строке )
    ошибка: ISO C++ не поддерживает сравнение между указателем и целым

    И с
    #define ALPHANUMERIC ( A || a || B || b || C || c || 1 || 2 || 3 )
    что не так? почему не верно #define ??
     
  5. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Может быть, следует обзавестись толковой книжкой и изучать последовательно материал, а не лезть вперёд?

    При более подробном изучении узнаешь, что макрос ALPHANUMERIC, который ты описал, - полный бред.

    Используй библиотеку <ctype.h>.
     
  6. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    SadKo

    Так поясните мне, почему подобный макрос берд??
    ( а кстати толковых книжек по си перечитал уже уйму...практикуюсь я )
    и почему при замене if( (char*)current_symbol == "#" ) на if(current_symbol == '#') происходит эта ошибка: ISO C++ не поддерживает сравнение между указателем и целым
     
  7. REASY

    REASY New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2007
    Сообщения:
    108
    stellaco
    Тебе нужно сравнить символ с символом, для этого нужно:
    if( current_symbol == '#' )
    а ты сравниваешь указатель со строкой, если допустим у тебя в current_symbol лежит 'a'(0x61),то (char*)current_symbol будет указывать на содержимое по адресу 0x00000061.

    и здесь
    Если ты хочешь вывести символ, то printf("current_symbol = %c \n", current_symbol) будет достаточно.
     
  8. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    REASY
    Офигеть) как просто оказывается...
    спасибо!! всё заработало =)

    и если можно, во избежании дальнейших моих глупых вопросов, задам ещё один для развеивания неясности.
    #define ALPHANUMERIC ( A || a || B || b || C || c || 1 || 2 || 3 )
    после прохода препроцессора, этот сишный код
    if ( symbol_ptr != ALPHANUMERIC )
    будет выглядить так?
    if ( symbol_ptr != ( A || a || B || b || C || c || 1 || 2 || 3 ) )
    Это выражение читаю так, если текущий символ не является одним из значений A || a || B || b || C || c || 1 || 2 || 3 .....то....
    Логика отработки кода будет верна?
     
  9. Rip

    Rip New Member

    Публикаций:
    0
    Регистрация:
    31 май 2009
    Сообщения:
    1
    Что-то не могу понять... Вроди, должно быть правильно:

    Код (Text):
    1. #include <stdio.h>
    2. int fd1=open("f1",O_READONLY);
    3. char msg[256];
    4. fgets(msg,256,fd1);
    5. printf("%s",msg);
    компилирую, запускаю, при fgets() - Segmentation fault.
    ???
     
  10. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    Rip
    может в f1 строка занимает больше 256 байт?
     
  11. REASY

    REASY New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2007
    Сообщения:
    108
    Rip
    Для функции fgets третий параметр - FILE *stream - то есть указаетль на структуру, а ты ему передаешь int fd1.
    По-моему будет правильнее так:
    FILE *fd1=fopen("f1","r");
    char msg[256];
    fgets(msg,sizeof(msg),fd1);
    printf("%s",msg);
     
  12. REASY

    REASY New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2007
    Сообщения:
    108
    stellaco
    пожалуйста.
    Если ты хочешь проверить, является ли символ буквами, цифрой и т.п., то используй функции isXXXXX(isdigit,isalpha,....). А если тебе нужна проверка на некоторые символы, то напиши для нее отдельную функцию.
    Код (Text):
    1. bool isMySymbol(char c)
    2. {
    3.     bool res = false;
    4.     char *symbols ="AaBbCc123\00";
    5.     while (c == *symbols++)
    6.     {
    7.         res = true;
    8.         break;
    9.     }
    10.     return res;
    11. }
     
  13. REASY

    REASY New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2007
    Сообщения:
    108
    Пардон, вот так надо:
    Код (Text):
    1. bool isMySymbol(char c)
    2. {
    3.     bool res = false;
    4.     char *symbols ="AaBbCc123\00";
    5.     int len = strlen(symbols);
    6.     for (int i = 0; i < len; i++)
    7.     {
    8.         if (c == symbols[i])
    9.         {
    10.             res = true;
    11.             break;
    12.         }
    13.         else
    14.             res = false;
    15.     }
    16.     return res;
    17. }
    PS:верните редактирование =)
     
  14. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    REASY
    Очень помогло )

    а почему вот тут char *symbols ="AaBbCc123\00"; .... в конце строка выглядит именно так? \00

    \0 это воспринимать так? \указывает что следующий символ, это литерал а не символ конца строки?
    а последний 0 .. означает конец сканируемой строки?
     
  15. REASY

    REASY New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2007
    Сообщения:
    108
    \00 == \0(ASCII код 0x00), да это символ конца строки. Его я использовал, чтобы быть уверенным что strlen() корректно посчитает длину строки. char *symbols ="AaBbCc123\00"; в памяти выглядит так 41 61 42 62 43 63 31 32 33 00. В конце видим завершающий ноль(0x00).
     
  16. stellaco

    stellaco New Member

    Публикаций:
    0
    Регистрация:
    11 дек 2008
    Сообщения:
    193
    REASY
    Спасибо за разъяснения, это мне ОЧЕНЬ помогло.
    Вынести проверку символов из макросов в функции, сделало код более понятным. ( а то спотыкаюсь почти на каждом шаге.... ) сейчас написано 113кб текста ... разобраться не так то легко (...а ведь это тока начало.
     
  17. REASY

    REASY New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2007
    Сообщения:
    108
    stellaco
    Пожалуйста, нет проблем.
    113 кБ о_О что же ты там кодишь ? =)
     
  18. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Боюсь, что какой-нибудь интерпретатор.