На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила трёх "С"
Пожалуйста,
1. Соблюдайте правила Форума.
2. Слушайте советы Модераторов.
(например, http://forum.sources.ru/index.php?act=ST&f=7&t=80382 )
3. Сверяйтесь с учебником по Великому и Могучему
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> C/C++ ... i need help :)
    Ваяю нечто... (Шедоу знает, что. :)) ...нечто, не вполне пока понятное. Вообще - мне нужен маленький биллинг моей сетки. В частности же мне нужно лог обработать... В C/C++ - ничего не шарю покамест. Нужен мне динамический массив пользователей...

    struct struser
        {
          char ip[16];
          char name[16];
          long bytes ;
        } ;
    int usercount=0;
    struser * users = new struser[usercount];

    //Вот тут я проверяю наличие в массиве пользователя:

    int indexof (char *ip)
     { int idx;
     for (idx=1; idx<=usercount; idx++)  if (strcmp (ip,users[idx].ip) == 0) {return idx; exit; }
      return 0;
     }


    // А вот тут я добавляю нового пользователя.
    int  adduser (char *ip)
    {

     if (indexof (ip)) { return 0; exit; }
                else
                        { usercount++;
                         realloc (users,  usercount*sizeof(struser));
                            sprintf (users[usercount].ip,"\%s",ip);
                      return usercount;
                      }

    }

    // А вот тут-то и грабли.
    int parselog(char *logfilename)
    {  

       char time[16],duration[16],client_ip[16],result[60],method[16],url[255],rfc931[255],code[60],type[255];
       long bytes;
       FILE *log;
       
       log = fopen(logfilename,"r");

    while (!feof(log))
     {
       fscanf (log, "\%s \%s \%s \%s \%d \%s \%s \%s \%s \%s",
                     time, duration, client_ip, result, &bytes, method, url, rfc931,code,type);

       printf ( "\%s \%s \%s \%s \%d \%s \%s \%s \%s \%s \n",
                     time, duration, client_ip, result, bytes, method, url, rfc931,code,type);
       
       adduser ("tralalalalala");}
       
       fclose (log);
    }


    int main(int argc, char *argv[])
    {

    parselog ("/usr/local/squid/var/logs/access.log.0");

    }


    -----------------------------------------------------------

    В общем, если убрать из тела функции parselog вызов adduser, то всё пройдёт замечательно. :) (Чему уж там проходить-то :)

    А вот если этот вызов оставить, то прога... зависает. Зависает на определённой строчке лога, и х...ит её постоянно, т.е. не переходит на следующую. Ctrl+c её обрубает, но обида и непонимание остаётся...

    Что я делаю не так? Может, это всё из-за realloc? :)
    Сообщение отредактировано: the_Shadow -
      Ммммм... Отмыль-ка сырец... Гляну. ;)
      Верну с комментариями... ;)
        Дык наверху весь сырец! :)

        Понял, что у меня sprintf там глючит. Однако, если написать в adduser

         users[usercount].ip = ip;

        вместо

         sprintf (users[usercount].ip,"\%s",ip);

        будем иметь ашипку:

        incompatible types in assignment of `char *' to `char[16]'
          2the_Shadow: ещё один клиент созрел (что за день) :D

          2Nwm:
          С++ всёже надо поизучать немного.
          А что касается твоей проблемы в " int parselog(char *logfilename) " - вставь перед   fscanf (....) вызов функции чтения строки из файла - fgets(buff, 256, log);
          вот к примеру как я парсю лог
           do
           {
            if(!fgets(fw_str, 256, ip_firewall)) break;
            //get count data from curent string
            sscanf(fw_str, "\%s\t\%s\t\%s\t\%[^]\n", fw_number, fw_pocket, fw_byte, fw_text);
            //it is this rule?
            if(atoi(fw_number) == number_rule)
            {
             //yes it is this rule!!!
             temp_pocket = atol(fw_pocket);
             temp_byte = atol(fw_byte);
             if(temp_pocket < pocket_count)
             {
              pocket_count += temp_pocket;
              byte_count += temp_byte;
             }
             else
             {
              pocket_count += (temp_pocket - pocket_count);
              byte_count += (temp_byte - byte_count);
             }
             break;
            }
           }
           while(!feof(ip_firewall));
            Блин почему все начинающие програмеры с упорством маньяков изобретают велосипед? Используй stl для таких вещей как списки, массивы, мэпы и множество проблем уйдёт сами сабой.
              А если делать
               
               strcpy (users[usercount].ip,ip);

              то опять повись на пустом месте...
                Цитата Aleks, 04.03.03, 17:58:33
                Блин почему все начинающие програмеры с упорством маньяков изобретают велосипед? Используй stl для таких вещей как списки, массивы, мэпы и множество проблем уйдёт сами сабой.


                1. Чё ещё за stl?
                2. fgets ничем не помог.
                  He can't use an stl (Standard Template Library), because he is writing in C, I guess...
                  Сообщение отредактировано: DEiL -
                    Цитата the_Shadow, 04.03.03, 18:11:28
                    He can't use an stl (Standard Template Library), because he is writing in C, I guess...


                    У тебя раскладку выбило? Или чего это? Или это не раскладка - что-то другое, более серьёзное? :)

                    He can use any library he has. And any compiler.

                    Если как-то можно сделать динамический массив из структуры с помошью стандартных cpp средств - то я буду рад, если вы ткнёте меня туда мордой. I guess.
                    Сообщение отредактировано: DEiL -
                      Цитата the_Shadow, 04.03.03, 18:11:28
                      He can't use an stl (Standard Template Library), because he is writing on C, I guess...


                      А вот эта строчка тебе... i guess... ни о чём не говорит? :)

                      struser * users = new struser[usercount];
                                       ^^^

                      Эта new имхо только в c++ возможна?
                        Nwm'у
                        А, да, невнимательно прочел... ;D Спать хочу. :(
                        Сейчас вот закончу писать и пойду. Sorry, так сказать... :)

                        Да и потом:

                        Обоим! И Aleks'у и Nwm'у!
                        А, коль скоро, ты используешь С++, то зачем тебе вообще связываться с fprintf/fscanf? В С++ для этого есть спец. средства типа iostream.

                        Смешанное программирование -- большая ошибка, парни! Дело в том, что синтаксически вы оба правы. Компилер проглотит и fscanf(), и многое другое из "чистого" С. Но вот семантически у вас бардак. Т.е. вы оба применяете функции из, по сути дела, другого языка... Т.е. теряется смысл С++.

                        2 Aleks.
                        Хэх! ;D вот и тут есть проблема. В твоем сырце... Дело в том, что использование функций как fgets, так и gets давным-давно признано потенциально небезопасным. Именно на этих функциях (на использовании их уязвимостей) и строятся атаки типа "переполнение буффера". Тогда уж проверяй каждый раз -- а именно ли 256 байт ты прочел из файла?
                        Для преодоления этих граблей есть какая-то библиотека -- сейчас не помню, а вспоминать лень -- глаза слипаются и пальцы не гнутся. потом расскажу... ;D

                        Не флейми. ;) У парня проблема, которую он, согласись решает руками и головой. Это отличает постановку проблемы от той, что есть у... посетителя Форума по имени COOOOL.

                        2 Nwm.
                        Спать хочу... Аххххххх (и, зевая, тормозит комп...)
                        Да! Не переругайтесь тут... Финские программисты... (тьфу ты!) парни... ;D ;D ;D
                        Завтрева продолжим разбор поле... сырцов.
                        Сообщение отредактировано: the_Shadow -
                          Цитата Aleks, 04.03.03, 17:50:14
                          2the_Shadow: ещё один клиент созрел (что за день) :D

                          вот к примеру как я парсю лог


                          Читается примерно так: "...что за день... вот я один раз в жизни спарсил один какой-то простецкий лог, и крутой до неузнаваемости.... а тут лезут всякие... с динами.... динамичес... динамическими массивами...".

                          Короче, ставлю вопрос иначе. Мне нужен динамический массив определённой структуры. Мой случай работает, но почему-то...

                          Цитата

                          int  adduser (char *ip)
                          {
                             if (indexof (ip)) { return 0; exit; }
                                else
                                              { usercount++;
                                              realloc (users,  usercount*sizeof(struser));
                                            strcpy (users[usercount].ip,ip);
                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                               
                                            return usercount;
                                            }

                          }


                          Вот эта фигня вешает цикл, который парсит лог. Если закомментировать //strcpy, то всё нормально. Т.е. у меня что-то с памятью происходит не то?

                          В общем, интересует реализация одномерного динамического массива какой-нибудь структуры.
                            the_Shadow Экзамл я привёл из Си проги, насчёт небезопасности данного кода... что ж озадочило меня твоё высказывание но лезть в старый код не охота, работает и х...н с ним.
                            2 Nwm зачем так злишся, да! Уж больно расплывчато ты начал "пишу сам не знаю чего, на не известном мне Си". Так вот Си все глюки в основном выползают из-за неумения работать с памятью. Поэтому я и предложил тебе использовать STL, там уже реализованны в виде классов динамические массивы, списки и т.д., добавление, удаление элементов и поиск по ним.
                            Кстати твой массив совсем не динамический, хоть он у тебя в куче выделяется - он свегда одного и того же размера "usercount".
                            Ну если ты загнался по чистому языку то вот тебе реализация на самом деле динамического связного списка - переделай в динамический массив...
                            допустим:
                            модифицирую твою структуру:
                            typedef struct struser
                                {  
                                  char ip[16];
                                  char name[16];
                                  long bytes ;
                                  typedef struct struser* pNext;
                                } SquidUser;

                            // Create user
                            SquidUser* createSquidUser(char* _name, char* _ip, long _bytes)
                            {
                                 SquidUser* pUser = NULL;
                                 pUser = (SquidUser*)malloc(sizeof(SquidUser));
                                 if(pUser)
                                 {
                                       memset(pUser, 0, sizeof(SquidUser));
                                       strcpy(pUser->name, _name);
                                       strcpy(pUser->ip, _ip);
                                       pUser->bytes = _bytes;
                                 }
                                 return pUser;
                            }

                            // Add user to list
                            void addSquidUser(SquidUser** ppHead, SquidUser* pNew)
                            {
                                 SquidUser* pUser;
                                 if(ppHead == NULL)
                                 {
                                       *ppHead == pNew;
                                 }
                                 else
                                 {
                                       pUser = *ppHead;
                                       while(pUser->pNext)
                                       {
                                             pUser = pUser->pNext;
                                       }
                                       pUser->pNext = pNew;
                                 }
                                 return;
                            }

                            // Освободить память занимаемую списком
                            void freeSquidUser(SquidUser** ppHead)
                            {
                                 SquidUser *pNext, *pUser;
                                 if(ppHead)
                                 {
                                       pUser = *ppHead;
                                       while(pUser)
                                       {
                                             pNext = pUser->pNext;
                                             free(pUser);
                                             pUser = pNext;
                                       }
                                 }
                                 return;
                            }

                            // Поиск юзера (рез-т надо проверять на NULL)
                            SquidUser* findSquidUser(SquidUser* pHead, char* pchName)
                            {
                                 while(pHead)
                                 {
                                       if(strcmp(pHead->name, pchName) == 0)
                                             break;
                                       pHead = pHead->pNext;
                                 }
                                 return pHead;
                            }

                            Пишу и думаю может тебе это и не нужно ни фига?... Ладно может кто ошибки найдёт и мне клёво будет!

                            ЗЫ: Если вдруг какие переменные или имена вдруг вылеэут откуда не возьмись - не удевляйся я ведь это на скорую руку из своих исходников переделал и наверняка что то пропустил.
                              Получается список... мне нужен массив. :)
                                Тут путей несколько:
                                1) Перегрузи оперцию... как она там называется... короче вот эту "[]"
                                2) Используй STL там уже всё сделано для людей!
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0432 ]   [ 15 queries used ]   [ Generated: 25.04.24, 05:35 GMT ]