Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.191.5.239] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток, уважаемые пользователи. Столкнулся с проблемой правильного перевода кода с языка Python на C++. Код на пайтоне решает следующую задачу:
1. Открыть бинарный файл udk_dump.bin 2. Выделить из потока нулевой и первый канал , сформировать и сохранить на диск один файл формата csv. Примечание: каждый байт представляет собой 1 отсчёт восьми каналов данных с параллельной шины, таким образом нулевому каналу соответствует нулевой бит, первому каналу - первый бит и тд. в csv-файле 3 колонки : нулевой канал, первый канал, нулевой канал логически умноженный на первый канал. Одна строчка = один отсчёт. 3. Декодировать информационный поток , т.е. выполнить дискретизацию сигнала относительно середины интервала между синхроимпульсами. Результат работы - csv файл с одной колонкой с отсчётами декодированного потока (т.е. значение 0 или 1 ). Одна строчка = один отсчёт. Примечание: нулевой и первый канал представляют собой информационный поток кода нулей и единиц (активный уровень нулевого канала = 0, активный уровень первого канала = 1), в обоих каналах присутствуют синхроимпульсы, предназначенные для определения точки сэмплирования. 4. Выделить из декодированного информационного потока кадры ТЕЛЕМЕТРИЧЕСКОЙ ИНФОРМАЦИИ, каждый из которых начинается с синхромаркера. В качестве синхромаркера используется 32-х разрядная последовательность: 0001 1010 1100 1111 1111 1100 0001 1101. 4.1. Определить размер кадра телеметрической информации 4.2. Сформировать пакеты ТМИ из полученных бит (от старшего к младшему) включая синхромаркер. 4.3. Записать полученные пакеты в бинарный файл out.bin. Вот, собственно, код на python, который правильно решает эту задачу: import struct def findsync(fileobj,updown=1,stepsize=1): while 1: byte = fileobj.read(stepsize) if not byte: return None comb = (byte[0]&1)&((byte[0]>>1)&1) if (comb==updown): return fileobj.tell() def sample(fileobj,synclen,bsynclen): syncpos = findsync(fileobj,updown=1,stepsize=synclen//4) if syncpos==None: return syncpos f.seek(synclen+bsynclen//2,1) byte = fileobj.read(1) if not byte: return None f.seek(synclen+bsynclen//4,1) return 0 if (byte[0]&1==1) else 1 f = open("udk_dump.bin", 'rb') ss,se =findsync(f,1),findsync(f,0) synclen = se-ss ss = findsync(f,1) bsynclen = ss-se sync =0b00011010110011111111110000011101 samples= 0 while (True): s =sample(f,synclen,bsynclen) if (s==None): break samples|=s if samples==sync: break samples = (samples<<1)&0xffffffff out = open("out.bin","wb") out.write(struct.pack(">I",samples)) counter=0 byte=0 while (True): s =sample(f,synclen,bsynclen) if (s==None): break byte|=s counter+=1 if (counter==8): counter = 0 out.write(struct.pack("B",byte)) byte=0 byte=byte<<1 out.close() Вот мой код на C++, который должен работать также, но выводит один единственный ноль в файл: #include<iostream> #include<fstream> using std::cout; using std::endl; using std::ifstream; using std::ofstream; int findSync(ifstream& fileObj, int upDown = 1, int stepSize = 1) { while(1) { char *byte = new char; fileObj.read(byte, stepSize); if(not *byte) return 0; int comb = (byte[0] & 1) & ((byte[0] >> 1) & 1); if(comb == upDown) return fileObj.tellg(); } } int sample(ifstream& fileObj, int syncLen, int bSyncLen) { int syncPos = findSync(fileObj, 1, syncLen/4); if(syncPos == 0) return syncPos; ifstream f; f.seekg(syncLen + bSyncLen/2, std::ios::cur); char *byte = new char; fileObj.read(byte, 1); if(not *byte) return 0; f.seekg(syncLen+bSyncLen/4, std::ios::cur); if((byte[0] & 1) == 1) return 0; else return 1; } int main() { ifstream f("/home/drfaust/forSending/udk_dump.bin", std::ios::binary); cout << "Hello\n"; if(f.fail()) { cout << "1_Error! Can't get access to the file\n"; exit(1); } int ss = findSync(f, 1), se = findSync(f, 0); int syncLen = se - ss; ss = findSync(f, 1); int bSyncLen = ss - se; int sync = 0b00011010110011111111110000011101; int samples = 0; while(true) { int s = sample(f, syncLen, bSyncLen); if (s == 0) break; samples |= s; if(samples == sync) break; samples = ((samples << 1) & 0xffffffff); } ofstream out("/home/drfaust/test/out.bin", std::ios::binary); if(out.fail()) { cout << "2_Error! Can't get access to the file\n"; exit(1); } out << samples; int counter = 0; int byte = 0; while(true) { int s = sample(f, syncLen, bSyncLen); if (s == 0) break; byte |= s; counter++; if(counter == 8) { counter = 0; out << byte; byte = 0; } byte = byte << 1; } out.close(); } Не могу понять где семантическая ошибка в коде на C++ и чем он отличается от кода на Python. Благодарю за внимание. |
Сообщ.
#2
,
|
|
|
HidenName, тебе нужно построчно пройтись и сверить идентичную ли операцию ты производишь на С++, даже если она кажется таковой.
К счастью я Питона не знаю, но беглый взгляд на С++ код намекает кагбэ ... Вот кусок, на Питоне: byte = fileobj.read(stepsize) Аналогичный ему на С++: char *byte = new char; fileObj.read(byte, stepSize); В Питоне для byte распределится столько памяти, сколько вернет fileobj.read(stepsize) А в С++ не так. У тебя создается в куче массив размером в 1 элемент. И как туда запишутся stepSize байтов? Ну и второй момент - ты в цикле там выделяешь и выделяешь память, а кто ее возвращать будет?? Поэтому данный кусок кода я бы переписал примерно так: int findSync(ifstream& fileObj, int upDown = 1, int stepSize = 1) { int ret = 0; char *byte = new char[stepSize]; while(1) { fileObj.read(byte, stepSize); if (fileObj.gcount() != stepSize) break; int comb = (byte[0] & 1) & ((byte[0] >> 1) & 1); if (comb == upDown) { ret = fileObj.tellg(); break; } } delete[] byte; return ret; } Хотя не уверен по логике, то ли делается. Но тем не менее по работе с памятью нужно что-то делать. А вообще, я бы поступил совершенно иначе - забил бы на эти ifstream, а использовал бы mmap. Дело в том, что при такой постановке задачи, сложно соорудить нужный итератор. Даже если и получится - глупая трата времени. А вот mmaр отобразит весь файл в массив байтов, по которому можно "прогуливаться" просто изменяя индекс. Мог бы помочь с кодом, но увы, пока для меня выражения типа "дискретизацию сигнала относительно середины интервала между синхроимпульсами" пустой звук, я просто не в теме. |
Сообщ.
#3
,
|
|
|
Цитата для меня выражения типа "дискретизацию сигнала относительно середины интервала между синхроимпульсами" пустой звук Это выражение значит наличие нуля в нулевом бите и единицы в первом Добавлено Цитата Мог бы помочь с кодом Буду Вам очень благодарен, за помощь |
Сообщ.
#4
,
|
|
|
Цитата HidenName @ Буду Вам очень благодарен, за помощь Тогда T3, начиная с п.3, нужно в терминах логики (а еще круче - с примерами). Иначе не понятно какие куски анализировать , как анализировать, и по какому условию выходить из цикла анализа. С тупым переписыванием с Питона не помогу - Питон не знаю и знать не желаю. |
Сообщ.
#5
,
|
|
|
Цитата HidenName @ Не могу понять где семантическая ошибка в коде на C++ и чем он отличается от кода на Python. Благодарю за внимание. Тем что это компилятор и он дает ошибки, Питон это по сути текстовой файл, который распарсивется тем а скорее С, if not byte: return None В C++ not это ! , а бинарный ~ , скажите простыми словами что нужно 1, Прочитать файл? проверить его побайтово ? Я не вовсем понимаю логику что именно проверять, 2, Записать файл как csv? это не проблема , В Питоне вы используете внешнюю библиотеку , что она делает ? потом вам надо найти анолог того же в C++, А может вам чистый С нужен? Так проще , Задайте конкретный вопрос как сделать на С++ то-то и то-то , тут вам видимо ответят , |