Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.133.156.156] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Ваяю нечто... (Шедоу знает, что. ) ...нечто, не вполне пока понятное. Вообще - мне нужен маленький биллинг моей сетки. В частности же мне нужно лог обработать... В 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? |
Сообщ.
#2
,
|
|
|
Ммммм... Отмыль-ка сырец... Гляну.
Верну с комментариями... |
Сообщ.
#3
,
|
|
|
Дык наверху весь сырец!
Понял, что у меня sprintf там глючит. Однако, если написать в adduser users[usercount].ip = ip; вместо sprintf (users[usercount].ip,"\%s",ip); будем иметь ашипку: incompatible types in assignment of `char *' to `char[16]' |
Сообщ.
#4
,
|
|
|
2the_Shadow: ещё один клиент созрел (что за день)
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)); |
Сообщ.
#5
,
|
|
|
Блин почему все начинающие програмеры с упорством маньяков изобретают велосипед? Используй stl для таких вещей как списки, массивы, мэпы и множество проблем уйдёт сами сабой.
|
Сообщ.
#6
,
|
|
|
А если делать
strcpy (users[usercount].ip,ip); то опять повись на пустом месте... |
Сообщ.
#7
,
|
|
|
Цитата Aleks, 04.03.03, 17:58:33 Блин почему все начинающие програмеры с упорством маньяков изобретают велосипед? Используй stl для таких вещей как списки, массивы, мэпы и множество проблем уйдёт сами сабой. 1. Чё ещё за stl? 2. fgets ничем не помог. |
Сообщ.
#8
,
|
|
|
He can't use an stl (Standard Template Library), because he is writing in C, I guess...
|
Сообщ.
#9
,
|
|
|
Цитата 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. |
Сообщ.
#10
,
|
|
|
Цитата 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++ возможна? |
Сообщ.
#11
,
|
|
|
Nwm'у
А, да, невнимательно прочел... ;D Спать хочу. Сейчас вот закончу писать и пойду. Sorry, так сказать... Да и потом: Обоим! И Aleks'у и Nwm'у! А, коль скоро, ты используешь С++, то зачем тебе вообще связываться с fprintf/fscanf? В С++ для этого есть спец. средства типа iostream. Смешанное программирование -- большая ошибка, парни! Дело в том, что синтаксически вы оба правы. Компилер проглотит и fscanf(), и многое другое из "чистого" С. Но вот семантически у вас бардак. Т.е. вы оба применяете функции из, по сути дела, другого языка... Т.е. теряется смысл С++. 2 Aleks. Хэх! ;D вот и тут есть проблема. В твоем сырце... Дело в том, что использование функций как fgets, так и gets давным-давно признано потенциально небезопасным. Именно на этих функциях (на использовании их уязвимостей) и строятся атаки типа "переполнение буффера". Тогда уж проверяй каждый раз -- а именно ли 256 байт ты прочел из файла? Для преодоления этих граблей есть какая-то библиотека -- сейчас не помню, а вспоминать лень -- глаза слипаются и пальцы не гнутся. потом расскажу... ;D Не флейми. У парня проблема, которую он, согласись решает руками и головой. Это отличает постановку проблемы от той, что есть у... посетителя Форума по имени COOOOL. 2 Nwm. Спать хочу... Аххххххх (и, зевая, тормозит комп...) Да! Не переругайтесь тут... Финские программисты... (тьфу ты!) парни... ;D ;D ;D Завтрева продолжим разбор поле... сырцов. |
Сообщ.
#12
,
|
|
|
Цитата Aleks, 04.03.03, 17:50:14 2the_Shadow: ещё один клиент созрел (что за день) вот к примеру как я парсю лог Читается примерно так: "...что за день... вот я один раз в жизни спарсил один какой-то простецкий лог, и крутой до неузнаваемости.... а тут лезут всякие... с динами.... динамичес... динамическими массивами...". Короче, ставлю вопрос иначе. Мне нужен динамический массив определённой структуры. Мой случай работает, но почему-то... Цитата 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, то всё нормально. Т.е. у меня что-то с памятью происходит не то? В общем, интересует реализация одномерного динамического массива какой-нибудь структуры. |
Сообщ.
#13
,
|
|
|
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; } Пишу и думаю может тебе это и не нужно ни фига?... Ладно может кто ошибки найдёт и мне клёво будет! ЗЫ: Если вдруг какие переменные или имена вдруг вылеэут откуда не возьмись - не удевляйся я ведь это на скорую руку из своих исходников переделал и наверняка что то пропустил. |
Сообщ.
#14
,
|
|
|
Получается список... мне нужен массив.
|
Сообщ.
#15
,
|
|
|
Тут путей несколько:
1) Перегрузи оперцию... как она там называется... короче вот эту "[]" 2) Используй STL там уже всё сделано для людей! |