Russian Qt Forum
Ноябрь 24, 2024, 11:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Класс-интерфейс для работы с DBF  (Прочитано 14853 раз)
Astrologer
Гость
« Ответ #15 : Октябрь 13, 2010, 13:44 »

Реализация есть. Чтением dbf я оттуда и пользуюсь Только после добавления столбцов в таблицу (я создаю таблицу из всех полей dbf + некие дополнительные параметры в виде дополнительных столбцов -> все это в базе). Ты уже ее не сохранишь правильно, не меняя кода. Точнее сказать мне не понравилось как у него организовано, поэтому проще сделать заново Улыбающийся
« Последнее редактирование: Октябрь 13, 2010, 14:02 от Astrologer » Записан
Astrologer
Гость
« Ответ #16 : Октябрь 14, 2010, 09:40 »

Никак не пойму. Вот смотри. Если запись типа "С" и не пустая, то
Код:
case 'C': 
Непонимающий
Записан
Astrologer
Гость
« Ответ #17 : Октябрь 14, 2010, 10:05 »

Я сделал так:
Код
C++ (Qt)
for (int zz = 0; zz < nr; ++zz)
   {
       if(codec) *b = codec->fromUnicode( QString::fromUtf8(" ") ).at(0);
       else *b = QString::fromUtf8(" ").at(0).toLatin1();
       b++;
 
       for(j = 0, p_fld = fld; j < dbfFieldCount; ++j, ++p_fld)
       {
          k = (unsigned short) p_fld->fieldLen[0];
          QString myString = myModel->record(zz).value(j).toString();//row = zz; column=j;
          if(myString.isNull()) str = QString(k, QString::fromUtf8(" ").at(0));
          else
          switch(p_fld->fieldType)
           {
            case 'D':
             //str = Fields->Fields[j]->toDate().toString("yyyyMMdd");
            break;
            case 'N':
             //str = QString::number(Fields->Fields[j]->toDouble(), 'f', 0 - Fields->Fields[j]->sqlScale());
             if(str.length() > k) str.resize( k );
             else str = QString(k - str.length(), QString::fromUtf8(" ").at(0)) + str;
            break;
            case 'C': str = myString;
            case 'L':
             //str = Fields->Fields[j]->toString();
             //if(str.length() > k) str.resize( k );
             //else str += QString(k - str.length(), QString::fromUtf8(" ").at(0));
            break;
           }
          if(codec) str = codec->fromUnicode( str );
          memcpy(b, str.toLatin1().data(), k);
          b += k;
       }
 
           ++i;
        if(i == recordCountDbfPortion)
        {
             fileStream.writeRawData(buf, i * hdr->recordSize);
             i = 0;
             b = buf;
        }
   }
 
Записан
Astrologer
Гость
« Ответ #18 : Октябрь 14, 2010, 10:58 »

Вроде все сохраняется. Спасибо тебе огромное. Очень выручил  Улыбающийся
Вопросик навскидку - мне надо сохранять выходной файл в кодировке IBM 866. Если указываю на входе в твоей функции -
Код
C++ (Qt)
QTextCodec::codecForName("IBM 866");
. То при открытии в программе  DBFCommander не определяется кодировка, а мне надо чтобы было "866 Russian MS-DOS". Есть какие нибудь мысли?
Записан
Zmeishe
Гость
« Ответ #19 : Октябрь 14, 2010, 11:20 »

1. Строки записываются как строки. Если строка короче длины поля, она дополняется пробелами справа.
2. Числа следует конвертировать в строку и дополнить пробелами слева.
И то и другое у меня есть.
Если строка пустая, она вся забивается пробелами.
Что и сделано
Код:
if(myString.isNull()) str = QString(k, QString::fromUtf8(" ").at(0));

Про IBM 866 ничего не знаю
За кодировку файла отвечают эти строки.
Код:
 if(codec == QTextCodec::codecForName("CP1251")) hdr->codePage = (unsigned char) 0x57;
    else if(codec == QTextCodec::codecForName("CP866")) hdr->codePage = (unsigned char) 0x26;
"866 Russian MS-DOS" это и есть "CP866"

Вызывай
Код:
saveToDBF(fileName, QTextCodec::codecForName("CP866"));
и будет тебе счастье.
Записан
Zmeishe
Гость
« Ответ #20 : Октябрь 14, 2010, 11:23 »

Если тебе нужны ещё кодировки кроме 1251 и 866,
выясни какой байт для них надо прописать в hdr->codePage = (unsigned char) XxXX ?
Записан
Zmeishe
Гость
« Ответ #21 : Октябрь 14, 2010, 11:28 »

В твоём коде ошибка.
Неправильно мой код под себя переделал
Код:
case 'C': str = myString;
case 'L':
              //str = Fields->Fields[j]->toString();
              //if(str.length() > k) str.resize( k );
              //else str += QString(k - str.length(), QString::fromUtf8(" ").at(0));
break;

Вот так надо
Код:
case 'C': 
case 'L':
               str = myString;
              if(str.length() > k) str.resize( k );
              else str += QString(k - str.length(), QString::fromUtf8(" ").at(0));
break;
Записан
Astrologer
Гость
« Ответ #22 : Октябрь 14, 2010, 11:32 »

То есть если case 'c' - то просто пусто?
Записан
Zmeishe
Гость
« Ответ #23 : Октябрь 14, 2010, 11:43 »

То есть если case 'c' - то просто пусто?

Вообще это стандарт Си для оператора switch.

case 'C':
case 'L':
 ...
break;

Означает что и для 'C' и для 'L' следует выполнить один и тот же кусок кода.
Учи мат - часть пригодится!
Записан
Astrologer
Гость
« Ответ #24 : Октябрь 14, 2010, 11:47 »

Аа... все)) никогда не любил switch. По мне if... else if ближе.
Записан
Astrologer
Гость
« Ответ #25 : Октябрь 14, 2010, 12:15 »

Спасибо еще раз. Все работает.
Записан
MoPDoBoPoT
Гость
« Ответ #26 : Октябрь 14, 2010, 20:17 »

Аа... все)) никогда не любил switch. По мне if... else if ближе.
[offtop]
"с програмерского форума:
наткнулись на багу VS2005 — после 128-го вложенного if-else-if условия просто напросто игнорируются. Пришлось переделать в switch-case" (c) bash.org.ru
[/offtop]
 Улыбающийся
Записан
Zmeishe
Гость
« Ответ #27 : Октябрь 15, 2010, 07:18 »

128 вложенных if-else-if условий - охренеть.
Они их руками писали или в VS2005 это мышетыканьем делается?

Записан
Sahab
Гость
« Ответ #28 : Октябрь 15, 2010, 08:49 »

это запросто реализуется boost.preprocessor`ом
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.096 секунд. Запросов: 20.