На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Перевод программы с Python на C++ , Программу обрабатывающую бинарный на файл, написанную на Python, перевести на C++
    Доброго времени суток, уважаемые пользователи. Столкнулся с проблемой правильного перевода кода с языка 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, который правильно решает эту задачу:
    ExpandedWrap disabled
      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++, который должен работать также, но выводит один единственный ноль в файл:
    ExpandedWrap disabled
      #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. Благодарю за внимание.
      HidenName, тебе нужно построчно пройтись и сверить идентичную ли операцию ты производишь на С++, даже если она кажется таковой.
      К счастью я Питона не знаю, но беглый взгляд на С++ код намекает кагбэ ...

      Вот кусок, на Питоне:
      ExpandedWrap disabled
        byte = fileobj.read(stepsize)

      Аналогичный ему на С++:
      ExpandedWrap disabled
        char *byte = new char;
        fileObj.read(byte, stepSize);

      В Питоне для byte распределится столько памяти, сколько вернет fileobj.read(stepsize)
      А в С++ не так. У тебя создается в куче массив размером в 1 элемент.
      И как туда запишутся stepSize байтов? Ну и второй момент - ты в цикле там выделяешь
      и выделяешь память, а кто ее возвращать будет??

      Поэтому данный кусок кода я бы переписал примерно так:

      ExpandedWrap disabled
        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р отобразит весь файл в массив байтов, по которому можно "прогуливаться" просто изменяя индекс.

      Мог бы помочь с кодом, но увы, пока для меня выражения типа "дискретизацию сигнала относительно середины интервала между синхроимпульсами" пустой звук, я просто не в теме.
        Цитата
        для меня выражения типа "дискретизацию сигнала относительно середины интервала между синхроимпульсами" пустой звук

        Это выражение значит наличие нуля в нулевом бите и единицы в первом

        Добавлено
        Цитата
        Мог бы помочь с кодом

        Буду Вам очень благодарен, за помощь
          Цитата HidenName @
          Буду Вам очень благодарен, за помощь

          Тогда T3, начиная с п.3, нужно в терминах логики (а еще круче - с примерами). Иначе не понятно какие куски анализировать , как анализировать, и по какому условию выходить из цикла анализа. С тупым переписыванием с Питона не помогу - Питон не знаю и знать не желаю.
            Цитата HidenName @
            Не могу понять где семантическая ошибка в коде на C++ и чем он отличается от кода на Python. Благодарю за внимание.

            Тем что это компилятор и он дает ошибки, Питон это по сути текстовой файл, который распарсивется
            тем а скорее С,

            ExpandedWrap disabled
                  if not byte:
                      return None


            В C++ not это ! , а бинарный ~ , скажите простыми словами что нужно
            1, Прочитать файл? проверить его побайтово ? Я не вовсем понимаю логику что именно проверять,
            2, Записать файл как csv? это не проблема , В Питоне вы используете внешнюю библиотеку ,
            что она делает ? потом вам надо найти анолог того же в C++,
            А может вам чистый С нужен? Так проще ,

            Задайте конкретный вопрос как сделать на С++ то-то и то-то , тут вам видимо ответят ,
            Сообщение отредактировано: sergioK -
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0287 ]   [ 17 queries used ]   [ Generated: 16.04.24, 09:53 GMT ]