Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Kate от Февраль 12, 2012, 23:41



Название: QBitArray
Отправлено: Kate от Февраль 12, 2012, 23:41
Подскажите, как можно переписать двоичные данные из одного большого массива типа QBitArray в другой?

При такой записи выводит ошибку переполнения массива.
QBitArray ba(200);
...
QBitArray time_s(13);
int f=0;

for (int l = 0; l < 12; ++l){
            time_s[f++]=ba[l];

}

и можно ли настроить отладчик,чтобы отображал данные в массиве побитно,а не побайтно?


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 13, 2012, 11:07
QBitArray & QBitArray::operator= ( const QBitArray & other )

Assigns other to this bit array and returns a reference to this bit array.

Стало быть.
Код
C++ (Qt)
time_s = ba;
time_s.truncate(12);


Название: Re: QBitArray
Отправлено: Kate от Февраль 13, 2012, 13:27
Это решает проблему,если нужны 1е элементы.А как быть,если нужна часть массива.Например с 12го бита до 32го?



Название: Re: QBitArray
Отправлено: Igors от Февраль 13, 2012, 13:37
Это решает проблему,если нужны 1е элементы.А как быть,если нужна часть массива.Например с 12го бита до 32го?
Код
C++ (Qt)
int CopyFrom( const QBitArray & src, QBitArray & dst, int srcBeg, int srcEnd, int dstBeg = 0 )
{
srcBeg = qMin(srcBeg, src.size());
srcEnd = qMin(srcEnd, src.size());
if (srcBeg >= srcEnd) return 0;
int dstSize = dstBeg + srcEnd - srcBeg;
if (dstSize > dst.size()) dst.resize(dstSize);
for (int i = srcBeg; i < srcEnd; ++i)
 dst[dstBeg++] = src[i];
return srcBeg - srcEnd;
}
 


Название: Re: QBitArray
Отправлено: Kate от Февраль 15, 2012, 19:24
Вот теперь только проблема,что данные неверно записываются.Если считывать весь файл побитно в один большой массив,а потом уже из него записывать поразрядно в массивы поменьше,записываются не те данные,кот были в большом файле.Не понятно почему так происходит.Если смотреть в отладчике,вместо [8,1,е] записывается [с,1,d]. Помогите разобраться. Изначально был дан двоичный файл.Из него необходимо считать 12 разрядов (0-11)-это секунды,затем 20 разрядов(12-32)-это микросекунды.

На данный момент код выглядит так:

int CopyFrom( const QBitArray & src, QBitArray & dst, int srcBeg, int srcEnd, int dstBeg = 0 )
{
 srcBeg = qMin(srcBeg, src.size());
 srcEnd = qMin(srcEnd, src.size());
 if (srcBeg >= srcEnd) return 0;
 int dstSize = dstBeg + srcEnd - srcBeg;
 if (dstSize > dst.size()) dst.resize(dstSize);
 for (int i = srcBeg; i < srcEnd; ++i)
  dst[dstBeg++] = src;
 return srcBeg - srcEnd;
}

void MainWindow::on_pushButton_clicked()
{
String fileName=QFileDialog::getOpenFileName(this, tr("Open File"),
                                                     "C:/ ",
                                                     tr("Files (*.a1311 *.c1211 *.s1311 *.txt)"));

QFile file1(fileName);
QFile file2("C:/72.txt");

QBitArray ba;

if (file1.open(QIODevice::ReadOnly)){
    qint64 sizeBytes = file1.size();
    if (sizeBytes) {
        char * temp = new char[sizeBytes];
        file1.read(temp, sizeBytes);
        ba.resize(sizeBytes * 8);
        for (int i = 0; i < sizeBytes; ++i)//отсчитывает количество байт
            for (int j = 0; j < 8; ++j)//для побитной записи файла
                ba.setBit(i * 8 + j, (temp >> j) & 1);
        delete [] temp;
    }
}

QBitArray time_s(12);
QBitArray time_ms(20);

int CopyFrom(ba,time_s,0,12,0);
int CopyFrom(ba,time_ms,12,32,0);

file1.close();
}




 



Название: Re: QBitArray
Отправлено: kambala от Февраль 15, 2012, 19:31
для вставки кода есть тэг code (а если написать code=cpp в открытии тега, то вывод будет красивым)
Код
C++ (Qt)
int CopyFrom(ba,time_s,0,12,0);
int CopyFrom(ba,time_ms,12,32,0);
зачем тут int впереди?

а ошибка во втором вызове в последнем параметре - там должна стоять 12 а не 0


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 15, 2012, 19:33
Вот мы и узнали, где собака зарыта)))
Итого нужно считать из файла один int и два раза поANDить например)


Название: Re: QBitArray
Отправлено: kambala от Февраль 15, 2012, 20:02
а ошибка во втором вызове в последнем параметре - там должна стоять 12 а не 0
а не, это моя невнимательность, вызов написан правильно.
Итого нужно считать из файла один int и два раза поANDить например)
int же на системах разной разрядности будет разной величины


Название: Re: QBitArray
Отправлено: _OLEGator_ от Февраль 15, 2012, 21:15
to kambala
Код
C++ (Qt)
qint8
qint16
qint32
qint64

Как бэ должны гарантировать разрядность int


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 15, 2012, 21:16
а ошибка во втором вызове в последнем параметре - там должна стоять 12 а не 0
а не, это моя невнимательность, вызов написан правильно.
Итого нужно считать из файла один int и два раза поANDить например)
int же на системах разной разрядности будет разной величины
ну я же условно. это ж похоже лабораторная работа.


Название: Re: QBitArray
Отправлено: Kate от Февраль 15, 2012, 23:03
Не понятно где и как прописать тег code.Но видимо дело не в красивом выводе,а что оно считывает биты как-то странно.
Нет,это не лаба,увы,это задание по работе и первая попытка реализовать что-то в QT(


Название: Re: QBitArray
Отправлено: kambala от Февраль 15, 2012, 23:37
процитируй чьё-нибудь сообщение с кодом и увидишь как пользоваться тегом

temp >> j - у меня такое даже не компилируется. а что эта запись должна делать? брать текущий char из массива и сдвигать его на нужное количество? тогда может
Код:
temp[i]
?


Название: Re: QBitArray
Отправлено: Kate от Февраль 15, 2012, 23:47
Да
Код:
temp[i]
.Без тегов не прописывалось как надо)


Название: Re: QBitArray
Отправлено: kambala от Февраль 15, 2012, 23:59
скорее всего биты просто читаются в обратном порядке, т.к. сам код по идее правильный. попробуй записывать биты в обратном порядке:
Код
C++ (Qt)
ba.setBit((i+1) * 8 - j - 1, (temp[i] >> j) & 1);


Название: Re: QBitArray
Отправлено: Igors от Февраль 16, 2012, 01:14
Изначально был дан двоичный файл.Из него необходимо считать 12 разрядов (0-11)-это секунды,затем 20 разрядов(12-32)-это микросекунды.
Зачем тогда QBitArray?

Код
C++ (Qt)
qint32 packedTime;
// читаем из файла
 
int seconds = packedTime & 0xFFF;
int msecs = (packedTime >> 12) & 0xFFFFF;
 
Общепринято что разряды идут справа налево, напр 0x0001 - единичка в нулевом разряде


Название: Re: QBitArray
Отправлено: GreatSnake от Февраль 16, 2012, 07:36
2 Igors:

Код
C
struct stime
{
   unsigned int seconds:12;
   unsigned int micro_seconds:20;
};

так ведь намного проще )


Название: Re: QBitArray
Отправлено: Kate от Февраль 16, 2012, 10:06
QBitArray нужен,тк исходный файл содержит больше 2 000 бит,ведь когда нужно будет считать,например,1345й бит,то на мой взгляд QBitArray - единственный выход.


Название: Re: QBitArray
Отправлено: GreatSnake от Февраль 16, 2012, 10:24
QBitArray нужен,тк исходный файл содержит больше 2 000 бит,ведь когда нужно будет считать,например,1345й бит,то на мой взгляд QBitArray - единственный выход.
Чего-то с теорией совсем слабовато. Единицей хранения данных в файлах является байт. И считывать вы будете байты. И извлекать "1345й бит" вы будете из 155-го байта.


Название: Re: QBitArray
Отправлено: BRE от Февраль 16, 2012, 10:27
И извлекать "1345й бит" вы будете из 155-го байта.
Пересчитал несколько раз, вроде 169 байт.  ::)


Название: Re: QBitArray
Отправлено: GreatSnake от Февраль 16, 2012, 10:33
Упс, опечатался - "извлекал" 1245-й бит)


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 16, 2012, 12:38
А зачем вообще извлекать отдельный бит? Какой смысл в одном бите?
Очевидно же, что читать надо интами.

QBitArray нужен,тк исходный файл содержит больше 2 000 бит,ведь когда нужно будет считать,например,1345й бит,то на мой взгляд QBitArray - единственный выход.
Интересно, когда Kate писала свое сообщение, она читала топик?


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 16, 2012, 12:41
2 Igors:

Код
C
struct stime
{
   unsigned int seconds:12;
   unsigned int micro_seconds:20;
};

так ведь намного проще )
Битовые поля железно упакуются в 32 бита? Мне кажется это зависит от "обстоятельств"? нет?


Название: Re: QBitArray
Отправлено: Igors от Февраль 16, 2012, 13:57
так ведь намного проще )
То да, но и по маске не умру  :)

QBitArray нужен,тк исходный файл содержит больше 2 000 бит,ведь когда нужно будет считать,например,1345й бит,то на мой взгляд QBitArray - единственный выход.
Ну "считали бит" - и что Вы будете с ним делать? Для манипуляций с (микро) секундами бит бесполезен - нужны значения для арифметики.


Название: Re: QBitArray
Отправлено: Kate от Февраль 16, 2012, 19:33
Нужно считывать 12 и 20 бит-это время,затем несколько раз по 12 бит на параметры,затем вся конструкция повторяется.Конечно,один бит не дает нужной информации.но нужна конструкция,кот начнет считывать с конретного бита,а не байта.Мне казалось,что сделать это возможно только через QBitArray,чтобы обращаться к любому месту в файле.


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 16, 2012, 21:02
Нужно считывать 12 и 20 бит-это время,затем несколько раз по 12 бит на параметры,затем вся конструкция повторяется.Конечно,один бит не дает нужной информации.но нужна конструкция,кот начнет считывать с конретного бита,а не байта.Мне казалось,что сделать это возможно только через QBitArray,чтобы обращаться к любому месту в файле.
жееееееесть!
вы меня конечно извините, но "логика женская. том первый". туши свет проще говоря)
весь тред впустую


Название: Re: QBitArray
Отправлено: Igors от Февраль 16, 2012, 21:47
жееееееесть!
вы меня конечно извините, но "логика женская. том первый". туши свет проще говоря)
весь тред впустую
А что такого уж страшного человек сказал? Ну может неправильно выразился "читать бит" - все равно придется читать байт (минимальную единицу информации) и из него извлекать бит. QBitArray здесь ничего не дает так как "превращать биты в число" все равно придется самому. В любом случае надо считать массив char и потом напр так
Код
C++ (Qt)
inline int GetBit( const char * src, int bitOfs )
{
return (src[bitOfs / 8] >> (7 - (bitOfs % 8))) & 1;
}
 
Эта ф-ция возвращает старший бит для меньшего bitOfs и младший для большего , использование
Код
C++ (Qt)
inline int GetNBits( const char * src, int bitOfs, int numBits )
{
int result = 0;
for (int i = 0; i < numBits; ++i)
 result = (result << 1) | GetBit(src, bitOfs + i);
return result;
}
 
numBits не должно превышать 32


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 17, 2012, 10:07
Судя по последнему посту, биты вообще не при чем. Там просто файл с данными упакованными в структуру.
Нужно просто выяснить его формат.
И скорее всего там все тривиально. И никаких мучений с битами не требуется.


Название: Re: QBitArray
Отправлено: Igors от Февраль 17, 2012, 11:28
Судя по последнему посту, биты вообще не при чем. Там просто файл с данными упакованными в структуру.
Читаем
Нужно считывать 12 и 20 бит-это время,затем несколько раз по 12 бит на параметры,затем вся конструкция повторяется.
Конечно куда проще запихнуть время в 32 бита (int) и параметры в 16 бит (short). Но если требуется напр 11 значений по 12 бит каждое, и они должны следовать подряд - извлекать биты придется


Название: Re: QBitArray
Отправлено: andrew.k от Февраль 17, 2012, 11:37
Судя по последнему посту, биты вообще не при чем. Там просто файл с данными упакованными в структуру.
Читаем
Нужно считывать 12 и 20 бит-это время,затем несколько раз по 12 бит на параметры,затем вся конструкция повторяется.
Конечно куда проще запихнуть время в 32 бита (int) и параметры в 16 бит (short). Но если требуется напр 11 значений по 12 бит каждое, и они должны следовать подряд - извлекать биты придется
Мы сейчас о чем спорим то? Что это невозможно сделать структурой? и "единственный выход это QBitArray"??


Название: Re: QBitArray
Отправлено: Kate от Февраль 20, 2012, 19:57
Спасибо,Igors.Ваши ответы очень помогли.