C/C++ ... i need help :)
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.43] |
|
|
Правила трёх "С"
| Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
C/C++ ... i need help :)
|
Сообщ.
#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 там уже всё сделано для людей! |