|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Ошибки новичков или индийский стиль... |
|
C/C++ - Ошибки новичков или индийский стиль...
|
Старожил Сообщения: 224 |
Профиль | Отправить PM | Цитировать Я написал небольшую программку. Хотел бы услышать мнения о том как она смотрится относительно идеологии C++. Т.е. незнаю возможно можно было как то сделать проще или лучше, записать короче и т.д. Зараннее спасиб
#include <vcl.h> #include <stdio.h> #include <iostream.h> #include <string.h> #pragma hdrstop #pragma argsused int main(int argc, char* argv[]) { FILE *binFile; char *cSect, *cKey, *cValue, *sPtr, *kPtr, bSect[512], bKeys[512], bValue[512], *cFile, MyPath[256], iniPath[256], MyDrive[2], MyDir[251]; cout << "Patcher started...\r\n"; GetModuleFileName(NULL,MyPath,sizeof(MyPath)); _splitpath(MyPath, MyDrive, MyDir, NULL, NULL); sprintf(iniPath,"%s%s%s", MyDrive,MyDir,"map.ini"); sprintf(MyPath,"%s%s", MyDrive,MyDir); cout << "Getting patch map...\r\n"; if (GetPrivateProfileString(NULL,NULL,FALSE,bSect,sizeof(bSect),iniPath) == 0) { cout << "Can't see map.ini\r\n" << "\r\n"; system("pause"); exit(1); } sPtr=bSect; while(*sPtr!=NULL)//перебираем буфер секций { cSect=(char*) malloc(strlen(sPtr)+1); strcpy(cSect,sPtr); sPtr=strchr(sPtr,'\0')+1; cFile=(char*) malloc(strlen(MyPath)+strlen(cSect)+1); sprintf(cFile,"%s%s",MyPath,cSect); binFile=fopen(cFile,"r+b"); printf("Patching %s:\r\n",cSect); if (binFile==NULL) { printf("\tCan't open file %s\r\n",cSect); system("pause"); exit(2); } GetPrivateProfileString(cSect,NULL,FALSE,bKeys,sizeof(bKeys),iniPath); kPtr=bKeys; while(*kPtr!=NULL) //перебираем ключи секции { cKey=(char*) malloc(strlen(kPtr)+1); strcpy(cKey, kPtr); kPtr=strchr(kPtr,'\0')+1; GetPrivateProfileString(cSect,cKey,FALSE,bValue,sizeof(bValue),iniPath); cValue=(char*) malloc(strlen(bValue)+1); strcpy(cValue,bValue); printf("\t%s=%s\r\n",cKey,cValue); fseek(binFile,atoi(cKey),0); fwrite(cValue, 1, strlen(cValue), binFile); }; fclose(binFile); } cout << "Patching done. Have a nice day :)...\r\n"; return 0; } |
|
------- Отправлено: 23:36, 29-08-2010 |
Старожил Сообщения: 232
|
Профиль | Сайт | Отправить PM | Цитировать Ну если прям так придираться, то:
1. я бы этот кусок как нибудь упростил, т.к тут используются 2 функции (strlen, strchr) которые совершают 2*N итераций, хотя можно было бы использовать только strchr и длину вычислять не с помощью strlen, а вычитанием sPtr от начального адреса. Что, касается strcpy, то я лучше бы использовал strncpy, т.к. переполнение буфера не кто не отменял (хотя тут мб и не будет такого...). 2. Уверены, что в cKey всегда будет строка из цифр? 3. Вызываем malloc, но забываем вызвать free. |
------- Отправлено: 01:27, 30-08-2010 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Старожил Сообщения: 224
|
Профиль | Отправить PM | Цитировать Цитата ganselo:
Скажем так... А что если использовать sizeof тоже ищет нуль терминатор как и strlen? Или?! Цитата ganselo:
Цитата ganselo:
Цитата ganselo:
|
||||
------- Отправлено: 10:23, 30-08-2010 | #3 |
Старожил Сообщения: 232
|
Профиль | Сайт | Отправить PM | Цитировать С помощью операции sizeof можно определить размер памяти которая соответствует идентификатору или типу. Если вы выделяете память char *c = malloc(...), то sizeof(c) вернёт, 1 байт. Так, что sizeof тут не прокатит.
Цитата Dr.Dark:
P.S Цитата Dr.Dark:
|
||
------- Отправлено: 13:19, 30-08-2010 | #4 |
Старожил Сообщения: 224
|
Профиль | Отправить PM | Цитировать Я ещё немног подумал над алгоритмом и немного упростил всё...
терь так выглядит #include <vcl.h> #include <stdio.h> #include <iostream.h> #include <string.h> #include <math.h> #pragma hdrstop #pragma argsused int hstoi(char* hexstr) { int idx, len, result; len=strlen(hexstr); strrev(hexstr); result=0; for(idx=0; idx<len; idx++) { if (isdigit(hexstr[idx])) { result+=(hexstr[idx]-48)*pow(16,idx); } else { switch(toupper(hexstr[idx])) { case 'A': result+=10*pow(16,idx);break; case 'B': result+=11*pow(16,idx);break; case 'C': result+=12*pow(16,idx);break; case 'D': result+=13*pow(16,idx);break; case 'E': result+=14*pow(16,idx);break; case 'F': result+=15*pow(16,idx);break; default: cout << "Incorrect offset"; exit(3); break; } } } return result; } int main(int argc, char* argv[]) { FILE *binFile; char *sPtr, *kPtr, *cFile, bSect[512], bKeys[512], bValue[512], MyPath[256], iniPath[256], MyDrive[2], MyDir[251]; cout << "Patcher started...\r\n"; GetModuleFileName(NULL,MyPath,sizeof(MyPath)); _splitpath(MyPath, MyDrive, MyDir, NULL, NULL); sprintf(iniPath,"%s%s%s", MyDrive,MyDir,"map.ini"); sprintf(MyPath,"%s%s", MyDrive,MyDir); cout << "Getting patch map...\r\n"; if (GetPrivateProfileString(NULL,NULL,FALSE,bSect,sizeof(bSect),iniPath) == 0) { cout << "Can't see map.ini\r\n" << "\r\n"; system("pause"); exit(1); } sPtr=bSect; while(*sPtr!=NULL)//перебираем буфер секций { cFile=(char*) malloc(strlen(MyPath)+strlen(sPtr)+1); sprintf(cFile,"%s%s",MyPath,sPtr); binFile=fopen(cFile,"r+b"); printf("Patching %s:\r\n",sPtr); if (binFile==NULL) { printf("\tCan't open file %s\r\n",sPtr); system("pause"); exit(2); } GetPrivateProfileString(sPtr,NULL,FALSE,bKeys,sizeof(bKeys),iniPath); kPtr=bKeys; while(*kPtr!=NULL) //перебираем ключи секции { GetPrivateProfileString(sPtr,kPtr,FALSE,bValue,sizeof(bValue),iniPath); printf("\t%s=%s\r\n",kPtr,bValue); fseek(binFile,hstoi(kPtr),0); fwrite(bValue, 1, strlen(bValue), binFile); kPtr=strchr(kPtr,'\0')+1; }; fclose(binFile); free(cFile); sPtr=strchr(sPtr,'\0')+1; } cout << "Patching done. Have a nice day :)\r\n"; return 0; } |
|
------- Отправлено: 22:11, 30-08-2010 | #5 |
ИО Капитана Очевидности Сообщения: 5387
|
Профиль | Отправить PM | Цитировать Цитата Dr.Dark:
Ну и конечно же,*если всё-таки хочется выделять память "руками", но нельзя забывать её освобождать замечания к функции int hstoi(char* hexstr) 1. Поскольку hexstr не изменяется, нужно использовать указатель на константу (иначе функция не сможет принимать константы в качестве аргументов) 2. В*цикле много раз выполняется операция pow(16,idx). Это жуткий "индуизм" , проще каждый раз в цикле выполнять операцию умножения. for(int idx=0, powdx=1; idx<len; idx++, powdx *= 16) А поскольку у нас значение кратное степеням двойки, то ещё быстрее будет логический сдвиг единицы в числе. 3. Мегабаг. Если в функцию будет направлена длинная строка, то произойдёт целочисленное переполнение значения powdx (равно как и результата исходного вычисления). Нужно добавить проверку значения len |
|
------- Отправлено: 04:46, 31-08-2010 | #6 |
Старожил Сообщения: 232
|
Профиль | Сайт | Отправить PM | Цитировать Цитата El Scorpio:
|
|
------- Отправлено: 17:21, 31-08-2010 | #7 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Доступ - "не удается войти в систему из-за следующей ошибки указанный домен не существует или | kalion-kill | Microsoft Windows 2000/XP | 23 | 22-11-2010 17:19 | |
Ноутбук для новичков | OSZone News | Новости информационных технологий | 0 | 20-02-2010 02:30 | |
Литература по администрированию для новичков | onefromheart | Microsoft Windows NT/2000/2003 | 11 | 24-10-2008 08:17 | |
Экстремально простая установка Ubuntu для новичков | liberatum | Новости и флейм из мира *nix | 1 | 16-10-2008 23:06 |
|