McZim
|
|
« : 29-07-2008 11:11 » |
|
Всем привет. Пишу замену, для себя, интерпретатора SQL, sqlplus. Основная проблема конечно же заключается в рисовании красивой таблицы, как у MySQL. У sqlplus даже с выставлением параметров типа "set page, set line" ничего хорошего не добиться. Так вот я и решил для себя сделать читаемый вывод данных по запросу. Пока мне нужно отрисовывать таблицу которая помещается на экран, т.е. пока не нужно заботиться о переводе строк или каком нибудь скролинге. Скролинг таблицы будет дальше с помощью библиотеки ncurses, но и там есть проблемы, скролинг на сколько я понял там только вертикальный, а мне еще понадобится скролинг горизонтальный, поэтому эту библиотеку скорее всего придется дорабатывать. И так сейчас проблема в следующем. Есть мой класс: class c_sqlplus { public: void f_execute(); void f_draw(SACommand*);
int len_f[1024]; int len_v[1024]; const char* buff_value[1024]; const char* buff_field[1024];
c_sqlplus(); ~c_sqlplus(); }; SACommand -- это класс библиотеки SQLAPI с помощью которой я общаюсь с БД Oracle. Внутри моей функции f_execute(); я захожу в другую мою функцию f_draw(SACommand*); передавая указатель на заранее созданный экземпляр класса, как видно из названия функции я рисую (таблицу): void c_sqlplus::f_draw(SACommand* cmd_in) { cmd_in = new SACommand; using namespace std;
for(int k=0; k<cmd_in->FieldCount(); k++) // { len_f[k] = strlen(buff_field[k]); len_v[k] = strlen(buff_value[k]); cout << "+";
if(len_f[k] > len_v[k]) { for(int i=0; i<len_f[k]; i++) cout << "-"; }
if(len_f[k] < len_v[k]) { for(int i=0; i<len_v[k]; i++) cout << "-"; }
//cout << "+"; } } рисовалка корявая пока что так вот если этот блок рисования поместить в основную функцию программы то все проходит хорошо, а если этот блок поместить в отдельную функцию, как сейчас то программа валится на Segmentation fault. Я не могу понять почему. Этот блок нужно держать в отдельной функции потому что повторяется несколько раз в основной функции. Дебагером воспользоваться не получается, потому что как только происходит con.Connect(instance, user, passwd, SA_Oracle_Client); установка соединения, дебагер завершает свою работу и говорит что программа выполнена. Подскажите что я не так делаю?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 29-07-2008 11:15 » |
|
код маленький, отследить строку, где вываливаемся, очень просто - закомментируй половину , запусти. Если не отвалилось, значит ошибка в коменте (и наоборот) , так найди строку с ошибкой
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #2 : 29-07-2008 11:18 » |
|
Алексей1153++, я комментировал всю функцию, f_draw() но вход в нее оставлял, и все равно падает. Я подозреваю что я как-то не так передаю указатель в эту функцию хотя вроде все просто. В общем башка кипит уже.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 29-07-2008 11:19 » |
|
а ещё, где гарантия, что массивы в этих строках len_f[k] = strlen(buff_field[k]); len_v[k] = strlen(buff_value[k]);
заканчиваются нулями ?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 29-07-2008 11:20 » |
|
а покажи пример вызова
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #5 : 29-07-2008 11:20 » |
|
Алексей1153++, это пока что тестовые массивы и я так думаю что на данное поведение оно не влияет
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Sla
|
|
« Ответ #6 : 29-07-2008 11:20 » |
|
McZim, посмотрел бы в сторону oracle forms, oracle reports
т.е. по сутьи дела, то что ты хочешь уже давно реализовано самим ораклом
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Вад
|
|
« Ответ #7 : 29-07-2008 11:20 » |
|
Я тоже думаю, что segmentation fault образуется где-то при выходе за границы массива. Кстати, почему так: const char* buff_value[1024]; const char* buff_field[1024];
?
|
|
« Последнее редактирование: 29-07-2008 11:22 от Вад »
|
Записан
|
|
|
|
McZim
|
|
« Ответ #8 : 29-07-2008 11:21 » |
|
void c_sqlplus::f_execute() { ... ... c_sqlplus::f_draw(cmd); ... }
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #9 : 29-07-2008 11:22 » |
|
Sla, я делаю это только по одной причине, по той что я очень много работаю удаленно с Oracle базамы по ssh и мне нужен удобный консольный инструмент.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #10 : 29-07-2008 11:24 » |
|
Алексей1153++, вот более детальней по поводу вызова функции: void c_sqlplus::f_execute() { ... ... SACommand* cmd = new SACommand; // create command object ... try { con.Connect(instance, user, passwd, SA_Oracle_Client); cmd->setConnection(&con); ... ... while(cmd->FetchNext()) { for(int k = 0; k < cmd->FieldCount(); k++) { buff_field[k] = cmd->Field(k+1).Name(); buff_value[k] = cmd->Field(k+1).asString(); } //----------------------------------------------------- c_sqlplus::f_draw(cmd); //----------------------------------------------------- ... ... } ... ... }
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Sla
|
|
« Ответ #11 : 29-07-2008 11:26 » |
|
так дело в том что существует консольная версия oracle formsa
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 29-07-2008 11:27 » |
|
и летит именно на строке c_sqlplus::f_draw(cmd); ? А если её закоментить ?
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #13 : 29-07-2008 11:32 » |
|
Sla, а нет ли случаем где нить скриншотов этого дела? гугл ничего не дал. Алексей1153++, странно, закоментил ошибка осталась но 100% если я вставлю блок из функции рисования в основную функцию, а функцию рисования убью то будет все рисоваться и не будет падать проверено.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 29-07-2008 11:36 » |
|
это может быть наведённая ошибка. Разбирайся с кодом до вызова )
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 29-07-2008 11:38 » |
|
например, должно быть, думается for(int k = 0; k+1 < cmd->FieldCount() && k<1024; k++)
|
|
|
Записан
|
|
|
|
|
McZim
|
|
« Ответ #17 : 29-07-2008 11:43 » |
|
Алексей1153++, я только что убил функцию рисования, из нее вынул код и вставил в те места где раньше был вызов функции рисования и все заработало, ничего не упало.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #18 : 29-07-2008 11:45 » |
|
Алексей1153++, массивы которые тебя смущают, могу заменить на вектора
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 29-07-2008 11:54 » |
|
Макс, при чём тут нафик вектора Ты пробовал с k+1 < ? Это точно косяк
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #20 : 29-07-2008 11:56 » |
|
Алексей1153++, пробовал та же петрушка, хотя с таким циклом (как у меня) нормально работает если без функции рисования.
|
|
« Последнее редактирование: 29-07-2008 12:00 от McZim »
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #21 : 29-07-2008 12:04 » |
|
Уже и так пробовал, думал может что то намудрил с указателями? SACommand cmd; // create command object
c_sqlplus::f_draw(&cmd);
void c_sqlplus::f_draw(SACommand*) { }
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #22 : 29-07-2008 12:05 » |
|
ну не знаю, на компилятор если ещё погрешить, то попробуй добавить в прототип рисовалки "cmd" , а не просто тип-указатель, а ещё при вызове функции убрать "класс::"
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #23 : 29-07-2008 12:06 » |
|
Алексей1153++, sudo aptitude show gcc [sudo] password for mczim: Пакет: gcc Состояние: установлен Автоматически установлен: да Версия: 4:4.2.3-1ubuntu6 Приоритет: необязательный Раздел: devel Сопровождающий: Ubuntu Core developers <ubuntu-devel-discuss@lists.ubuntu.com> Размер в распакованном виде: 65,5k Зависимости: cpp (>= 4:4.2.3-1ubuntu6), gcc-4.2 (>= 4.2.3-1) Рекомендует: libc6-dev | libc-dev Предлагает: autoconf, automake1.9, bison, flex, gcc-doc, gcc-multilib, gdb, libtool, make, manpages-dev Конфликтует: gcc-doc (< 1:2.95.3) Предоставляет: c-compiler Описание: компилятор GNU C Это компилятор GNU C, весьма портабельный оптимизирующий компилятор языка С.
Этот пакет зависимостей предоставляет компилятор по умолчанию GNU C.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #24 : 29-07-2008 12:24 » |
|
ну собственно все понятно!!! Воспользовавшись программой valgrind, увидел слудующее ==13941== ==13941== Use of uninitialised value of size 4 ==13941== at 0x80499C4: c_sqlplus::f_execute() (main.cpp:72) ==13941== by 0x8049EB5: main (main.cpp:7) ==13941== ==13941== Process terminating with default action of signal 11 (SIGSEGV) ==13941== Bad permissions for mapped region at address 0x4010DC0 ==13941== at 0x80499C4: c_sqlplus::f_execute() (main.cpp:72) ==13941== by 0x8049EB5: main (main.cpp:7) ==13941== ==13941== ERROR SUMMARY: 1790 errors from 192 contexts (suppressed: 80 from 1) ==13941== malloc/free: in use at exit: 1,281,487 bytes in 540 blocks. ==13941== malloc/free: 1,386 allocs, 846 frees, 1,395,502 bytes allocated. ==13941== For counts of detected errors, rerun with: -v ==13941== searching for pointers to 540 not-freed blocks. ==13941== checked 2,082,012 bytes. ==13941== ==13941== LEAK SUMMARY: ==13941== definitely lost: 8,976 bytes in 20 blocks. ==13941== possibly lost: 10,843 bytes in 23 blocks. ==13941== still reachable: 1,261,668 bytes in 497 blocks. ==13941== suppressed: 0 bytes in 0 blocks. ==13941== Rerun with --leak-check=full to see details of leaked memory. Segmentation fault
смотрим вот сюда ==13941== at 0x80499C4: c_sqlplus::f_execute() (main.cpp:72), смотрим в код и видим что строка 72 это: buff_field[k] = cmd.Field(k+1).Name(); valgrind - a suite of tools for debugging and profiling programs мда...
|
|
« Последнее редактирование: 29-07-2008 12:26 от McZim »
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #25 : 29-07-2008 12:49 » |
|
хм, заменил строку buff_field[k] = cmd.Field(k+1).Name(); на field.push_back((const char*)cmd.Field(k+1).Name());, соответственно описав вектор std::vector<std::string> field;видим теперь такое: SQL> select * from bm_staff; ==15828== ==15828== Use of uninitialised value of size 4 ==15828== at 0x804A8D9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:599) ==15828== by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72) ==15828== by 0x804A0A3: main (main.cpp:7) ==15828== ==15828== Use of uninitialised value of size 4 ==15828== at 0x804A8DF: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:599) ==15828== by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72) ==15828== by 0x804A0A3: main (main.cpp:7) ==15828== ==15828== Use of uninitialised value of size 4 ==15828== at 0x804A8E9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:601) ==15828== by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72) ==15828== by 0x804A0A3: main (main.cpp:7) ==15828== ==15828== Invalid write of size 4 ==15828== at 0x41AB680: std::string::_Alloc_hider::_Alloc_hider(char*, std::allocator<char> const&) (basic_string.h:242) ==15828== by 0x41A7E48: std::string::string(std::string const&) (basic_string.tcc:188) ==15828== by 0x804A32C: __gnu_cxx::new_allocator<std::string>::construct(std::string*, std::string const&) (new_allocator.h:107) ==15828== by 0x804A903: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:601) ==15828== by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72) ==15828== by 0x804A0A3: main (main.cpp:7) ==15828== Address 0x8b1572ec is not stack'd, malloc'd or (recently) free'd ==15828== ==15828== Process terminating with default action of signal 11 (SIGSEGV) ==15828== Access not within mapped region at address 0x8B1572EC ==15828== at 0x41AB680: std::string::_Alloc_hider::_Alloc_hider(char*, std::allocator<char> const&) (basic_string.h:242) ==15828== by 0x41A7E48: std::string::string(std::string const&) (basic_string.tcc:188) ==15828== by 0x804A32C: __gnu_cxx::new_allocator<std::string>::construct(std::string*, std::string const&) (new_allocator.h:107) ==15828== by 0x804A903: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:601) ==15828== by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72) ==15828== by 0x804A0A3: main (main.cpp:7) ==15828== ==15828== ERROR SUMMARY: 1802 errors from 195 contexts (suppressed: 80 from 1) ==15828== malloc/free: in use at exit: 1,281,508 bytes in 541 blocks. ==15828== malloc/free: 1,389 allocs, 848 frees, 1,395,551 bytes allocated. ==15828== For counts of detected errors, rerun with: -v ==15828== searching for pointers to 541 not-freed blocks. ==15828== checked 2,082,108 bytes. ==15828== ==15828== LEAK SUMMARY: ==15828== definitely lost: 8,976 bytes in 20 blocks. ==15828== possibly lost: 10,864 bytes in 24 blocks. ==15828== still reachable: 1,261,668 bytes in 497 blocks. ==15828== suppressed: 0 bytes in 0 blocks. ==15828== Rerun with --leak-check=full to see details of leaked memory. Segmentation fault
Address 0x8b1572ec is not stack'd, malloc'd or (recently) free'd, что же за напасть такая вротмненоги
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #26 : 29-07-2008 12:52 » |
|
кстате какая конструкция более приемлема с точки зрения передачи указателя в функцию? SACommand cmd; f_draw(&cmd); или SACommand* cmd = new SACommand; f_draw(cmd); или на вкус и цвет пошел на ..уй
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #27 : 29-07-2008 13:27 » |
|
McZim, первое предпочтительнее, если можно обойтись без второго. Иногда можно только второй вариант применить. А сама передача указателя - в обоих случаях один хрен )
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #28 : 29-07-2008 13:28 » |
|
Алексей1153++, ясно.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #29 : 29-07-2008 13:30 » |
|
Макс, ну в баню вектор, ни при чём он, не в работе с масивами ошибка , поробуй так (и не забывай про k+1 !!!!!!!! Это же важно, иначе твой cmd->Field(k+1) - это косяк) while(cmd->FetchNext()) { for(int k = 0; k+1 < cmd->FieldCount(); k++) { buff_field[k] = "111"/*cmd->Field(k+1).Name()*/; buff_value[k] = "222"/*cmd->Field(k+1).asString()*/; }
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #30 : 29-07-2008 13:38 » |
|
хотя, насчёт k+1 , от тебя требуется уточнение - параметр Field - это zb индекс ?
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #31 : 29-07-2008 13:40 » |
|
Алексей1153++, ==20503== Process terminating with default action of signal 11 (SIGSEGV) ==20503== Bad permissions for mapped region at address 0x4010DC0 ==20503== at 0x8049754: c_sqlplus::f_execute() (main.cpp:72) ==20503== by 0x8049BBB: main (main.cpp:7) мне массивы все равно переделывать и собственно пока заморачиваться не охото над их размером и размещением в памяти, пусть будут вектора, но я сделал что ты просил ошибка выше!
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #32 : 29-07-2008 13:42 » |
|
Алексей1153++, на счет к+1 думаю ты не прав, так как до создания отдельной функции рисования все работало, проблемы начались именно с появлением функции. Что за zb индекс ?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #33 : 29-07-2008 13:49 » |
|
Макс, а вот это чё за фигня void c_sqlplus::f_draw(SACommand* cmd_in) { cmd_in = new SACommand; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
? ты же снаружи создал уже объект, а тут снова создаёшь
|
|
« Последнее редактирование: 29-07-2008 13:51 от Алексей1153++ »
|
Записан
|
|
|
|
McZim
|
|
« Ответ #34 : 29-07-2008 13:51 » |
|
Алексей1153++, у меня там уже все закоменчено ВСЯ ФУНКЦИЯ!!!
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #35 : 29-07-2008 13:59 » |
|
Макс, вот это работает, я проверил (вылетало чисто изза к+1 - у тебя в двух местах это. И изза неинициализированных массивов ) class c_sqlplus { public: void f_execute(); void f_draw(/*SACommand*/BYTE* cmd_in);
int len_f[1024]; int len_v[1024]; const char* buff_value[1024]; const char* buff_field[1024];
c_sqlplus(); ~c_sqlplus(); };
c_sqlplus::c_sqlplus() { }
c_sqlplus::~c_sqlplus() { }
void c_sqlplus::f_draw(/*SACommand*/BYTE* cmd_in) { //cmd_in = new SACommand; // using namespace std;
for(int k=0; k+1<10/*cmd_in->FieldCount()*/; k++) // { len_f[k] = strlen(buff_field[k]); len_v[k] = strlen(buff_value[k]); // cout << "+";
if(len_f[k] > len_v[k]) { for(int i=0; i<len_f[k]; i++); //cout << "-"; }
if(len_f[k] < len_v[k]) { for(int i=0; i<len_v[k]; i++); //cout << "-"; }
//cout << "+"; } }
void c_sqlplus::f_execute() {
/*SACommand*/BYTE* cmd = new BYTE/*SACommand*/; // create command object
try { // con.Connect(instance, user, passwd, SA_Oracle_Client); // cmd->setConnection(&con);
// while(cmd->FetchNext()) // { for(int k = 0; k+1 < 10/*cmd->FieldCount()*/; k++) { buff_field[k] = "111";//cmd->Field(k+1).Name(); buff_value[k] = "222";//cmd->Field(k+1).asString(); } //----------------------------------------------------- f_draw(cmd); //----------------------------------------------------- } catch(...) { int iii=1; } int iii=1;
}
c_sqlplus ttt; ttt.f_execute();
ещё я не использовал класс SACommand , может в нём дело
|
|
« Последнее редактирование: 30-07-2008 06:19 от Алексей1153++ »
|
Записан
|
|
|
|
McZim
|
|
« Ответ #36 : 29-07-2008 14:06 » |
|
если все закоментить оставить лишь выше описанное подключение, которое 100% рабочее и вот это while(cmd.FetchNext()) { for(int k = 0; k+1 < cmd.FieldCount(); k++) { cout << ok << endl; //field[k] = "11";//cmd.Field(k+1).Name(); //value[k] = "222"; //field.push_back((const char*)cmd.Field(k+1).Name()); //value.push_back((const char*)cmd.Field(k+1).asString()); } } то все гуд, работает, а если сделать вот так: while(cmd.FetchNext()) { for(int k = 0; k+1 < cmd.FieldCount(); k++) { field[k] = "11";//cmd.Field(k+1).Name(); //value[k] = "222"; //field.push_back((const char*)cmd.Field(k+1).Name()); //value.push_back((const char*)cmd.Field(k+1).asString()); } } то падает вот так: ==21886== Process terminating with default action of signal 11 (SIGSEGV) ==21886== Bad permissions for mapped region at address 0x400FDC0 ==21886== at 0x804974D: c_sqlplus::f_execute() (main.cpp:72) ==21886== by 0x80499C3: main (main.cpp:7)
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #37 : 29-07-2008 14:16 » |
|
останавливайся брекпоинтом на строке field[k] = "11";// и показывай значения: к== ? field[k] ==? *field[k] ==?
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #38 : 29-07-2008 14:18 » |
|
Какое значение возвращает cmd.FieldCount()? Кстати, то, что он вызывается каждую итерацию - это нормально? Какая размерность у field?
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #39 : 29-07-2008 15:08 » |
|
Алексей1153++, ) я же говорю что не могу воспользоваться дебагером.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #40 : 29-07-2008 15:12 » |
|
McZim, ну а твой любимый cout для чего ? )
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #41 : 29-07-2008 15:12 » |
|
Вад, 1. значение возвращается равное количеству стобцов в одной записи. 2. а что тут не нормального, проверяем в цткле "к" больше оно общего количества или нет. обычный цикл. 3. размерность 1024. это для тестов.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #42 : 29-07-2008 15:13 » |
|
Алексей1153++, зачем cout когда есть хороший инструмент как valgrind, который любезно ссобщает что я херово работаю с памятью.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #43 : 29-07-2008 15:22 » |
|
просто ты как-то неправильно используешь указатель field+k , я сейчас не могу понять
то есть значение &(field[k]) при некотором k указывает на память, которую уже нельзя пользовать
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #44 : 29-07-2008 15:28 » |
|
Алексей1153++, да возможно, ночекром буду разбираться.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #45 : 29-07-2008 18:44 » |
|
В общем проблема решилась, оказалось дело в моей не внимательности. c_sqlplus* sql; sql->f_execute(); а нужно: c_sqlplus* sql = new c_sqlplus(); sql->f_execute(); Алексей1153++, скажи почему ты такой упор делаешь на k+1 я никак не пойму в чем ошибка?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #46 : 30-07-2008 04:33 » |
|
ну смотри: к примеру, Counter() у тебя вернёт 10. у тебя в цикле: for(k=0;k<10;k++) { GetField(k+1); }
если GetField() должно принимать zb индекс, то оно на последней итерации получит 10 (а можно только 0...9) По.тому условие должно быть k<10 && k+1<10 или просто k+1<10
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #47 : 30-07-2008 05:59 » |
|
Алексей1153++, не ты не прав GetField(k+1), а в моем случае cmd.Field(k+1) это номер столбца в таблице из которой я вынимаю имена столбцов и значения столбцов. Если я укажу просто cmd.Field(k), то программа упадет при первом проходе в цикле, потому как нумерация столбцов начинается не с 0 а с 1. А цикл остается обычный чтобы пройти по всем значениям. от 0 до 9 (допустим).
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #48 : 30-07-2008 06:16 » |
|
ну тогда всё правильно, значит индекс передаётся как не zb
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #49 : 30-07-2008 06:58 » |
|
Вад, 2. а что тут не нормального, проверяем в цткле "к" больше оно общего количества или нет. обычный цикл.
Ну, если там inline-подстановка выполнится, то ничего такого. Если же там идёт, скажем, трансляция вызова дальше, чтобы получить-таки общее количество откуда-то "из глубин", то, возможно, выполняется лишняя работа. Поэтому и спросил
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #50 : 30-07-2008 07:46 » |
|
Все работает Пока использую для хранения имен полей и значений полей: std::vector<std::string> value; std::vector<std::string> field; для длин этих полей: unsigned int len_f[1024]; unsigned int len_v[1024]; пока не определился что нужно, STL не очень люблю, но пока освобождает от думы про размерность
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #51 : 30-07-2008 08:28 » |
|
тоже не люблю STL, но сделал бы так struct sNL { std::string name; unsigned int len; sNL() { name=""; len=0; } };
std::vector<sNL> values; std::vector<sNL> fields;
(не компилил, правда, проверить не могу ) )
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #52 : 08-08-2008 08:31 » |
|
Всем привет. В продолжение проекту. Я работаю с ораклом используя библиотеку libsqlapi.so и вот что странно. Создан проект, в линкере указана эта библиотека, все работало, я удалил эту библиотеку из списка подключаемых в проекте, не пересобирая проект, тут же ее добавил, начал собирать проект и посывались ошибки: ||=== sqlplus-new, Debug ===| /lib/../lib/libsqlapi.so||undefined reference to `dlsym'| /lib/../lib/libsqlapi.so||undefined reference to `dlerror'| /lib/../lib/libsqlapi.so||undefined reference to `dlopen'| /lib/../lib/libsqlapi.so||undefined reference to `dlclose'| ||=== Build finished: 4 errors, 0 warnings ===|
т.е. видно что проблема не в библиотеки и не в том что ее линкер не находит. После этого иду в консоль, выполняю: gcc main.cpp -l /lib/libsqlapi
и вижу вот такую ошибку: /usr/bin/ld: cannot find -l/lib/libsqlapi collect2: выполнение ld завершилось с кодом возврата 1
никак не могу понять, как оно только что работало а теперь не работает. причем заметьте, когда выполняю компиляцию в консоле линкер не может найти библиотеку, очень странно. З.Ы.: пробовал собирать под рутом, та же ситуация.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
|
|
« Ответ #53 : 08-08-2008 08:42 » |
|
McZim, подключи библиотеку libdl (dynamic library -- -ldl) и добавь в сборку ключик -shared.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #54 : 08-08-2008 08:47 » |
|
RXL, 5+ спасибо, оно самое, ключик -shared не понадобился.
Вот только не понятно почему поведение разное??? Работало-работало, потом не работает?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
|
|
« Ответ #55 : 08-08-2008 09:30 » |
|
В процессе работы делай копии и потом сравнивай, что изменилось - только так.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #56 : 26-08-2008 10:23 » |
|
Предыстория: вектор мне нужно иметь обязательно string, положить я в него в чистом виде из Field(k+1).Name() немогу, могу через преобразование в const char*. Все хорошо, но как только мне в БД встречаются строки состоящие из русских букв, у меня рисование рамки начинает смещаться, все потому что длина русских и английских разная, т.е. мне нужно уметь работать со строками, пока что мной было принято решение воспользоваться не string а wstring, соответственно, в такой вектор я могу положить тип const wchar_t*, но его не понимает Field(k+1).Name(), вот и решил делать через преобразование типов, конечно понимаю что лучше всего это избежать, но пока не знаю как, не работал я с кодировками и символами, может кто подскажет по лучше способ, а пока что: Вот так все замечательно работает: typedef std::vector<std::string> column_t; column_t col; col.push_back((const char*)cmd.Field(k+1).Name()); а вот так не работает, т.е. работает но на выходе я получаю не значения а адреса памяти, где то запарился с указателями, не могу понять где? typedef std::vector<std::wstring> column_t; column_t col; col.push_back(static_cast<const wchar_t*>(static_cast<const void*>(cmd.Field(k+1).Name())));
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
|
|
« Ответ #57 : 26-08-2008 10:32 » |
|
McZim, Oracle у тебя возвращает в какой кодировке? Строка NLS какая? Я так понял, что utf-8.
Соотв., в wchar_t != utf-8 - это unicode 16 бит.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #58 : 26-08-2008 10:35 » |
|
ага utf-8, вот гадство блин кстате не знаешь как можно раотать с разными кодировками? У меня могут встречать кодировки, utf-8, koi8-r
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #59 : 26-08-2008 17:50 » |
|
итак: int main() { string str1; cin >> str1; cout << endl << "You print string: " << str1 << endl; cout << "length string: " << str1.length() << endl;
return 0; }
результат: mczim@mczim-desktop:# ./1 Input string: qwerty
You print string: qwerty length string: 6
mczim@mczim-desktop:# ./1 Input string йцукен
You print string: йцукен length string: 12
применимо к моей прграмме (sqlplus), если я считываю из базы строку состоящую из русских символов, то при том же количестве символов я получаю совершенно другую длину строки, в следствии чего у меня происходит смещение рисования таблицы, основанное на длине строки.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
|
|
« Ответ #60 : 27-08-2008 06:20 » |
|
McZim, setlocale(). Ф-ии стандартной библиотеки должны уметь работать с mb (multi byte)
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #61 : 27-08-2008 06:35 » |
|
Я просто никак не могу понять что мне нужно В общем проблема не влокали, т.е. все буквы отображаются корректно, кракозяблов нет, в посте выше в примере я просто qwerty набирал на русском, поэтому в таком порядке буквы, но они все нормальные сейчас думаю сделать так, проверять полученную строку на содержание в ней русских символов, каждый символ проверять на то является ли он русской буквой, потому как в одной строке могут быть и английские буквы, если символ русский то брать его длину -1, так как для русской буквы в utf-8 отводится 2 байта, а для английской 1. я туда мыслю?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
|
|
« Ответ #62 : 27-08-2008 06:38 » |
|
Не правильно мыслишь. ASCII - 1 байт, все остальное - 2+ байт. Причем в тексте может не быть ни одной кириллической буквы, но не-ASCII могут присутствовать.
1. Установи локаль. 2. Используй стандартные ф-ии strlen и т.п.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #63 : 27-08-2008 06:39 » |
|
ок, твои предложения?
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #64 : 27-08-2008 11:40 » |
|
я сейчас работаю так: отрывок кода typedef std::vector<std::string> column_t; typedef std::vector<column_t> table_t;
table_t m_table;
std::vector<unsigned int> lengths;
for(unsigned int k = 0; k < m_table.size(); k++) { unsigned int len = 0; for(unsigned int l = 0; l < m_table[k].size(); l++) { if(len < m_table[k][l].length()) { len = m_table[k][l].length(); } } lengths.push_back(len); }
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
McZim
|
|
« Ответ #65 : 27-08-2008 12:19 » |
|
проблема не в том что я не могу определить длину или корректно напечатать символы, а в том что при прорисовки таблицы, разделители имеют длину в два раза больше нежели это необходимо, я не зря привел пример в посте #59. вот http://picasaweb.google.com/mczimm/NfxadF/photo#5238897000859988066 скрин того что получается, первым запросом видно что длина разделителей намного длиннее полей, что в заголовке что в теле таблицы. З.Ы.: увеличить можно справа в углу.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
|