DrFaust
New member
- 14.08.2019
- 2
- 0
Доброго времени суток, уважаемые пользователи. Столкнулся с проблемой правильного перевода кода с языка 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, который правильно решает эту задачу:
Вот мой код на C++, который должен работать также, но выводит один единственный ноль в файл:
Не могу понять где семантическая ошибка в коде на C++ и чем он отличается от кода на Python. Благодарю за внимание.
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, который правильно решает эту задачу:
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++, который должен работать также, но выводит один единственный ноль в файл:
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();
}