0

Byte Pair Encoding を使用してバイト配列を解凍したいと考えています。私が持っているソースコード(私からのものではありません)は、ファイルストリームを使用してファイルをバイト単位で読み取ります。しかし、私は解凍したいchar *

stringstream などを使用してこれを変換しようとしていますが、これを行う方法がわかりません。

次のように使用したいと思います。expand(char *inputarray, char *outputarray)

私はc ++を初めて使用し、vb.netから切り替えたばかりなので、あまり苦労しないでください:)

これはコードです:

/* expand.c */
/* Copyright 1994 by Philip Gage */

#include <stdio.h>

/* decompress data from input to output */
void expand (FILE *input, FILE *output)
{
  unsigned char left[256], right[256], stack[30];
  short int c, count, i, size;

  /* unpack each block until end of file */
  while (( count = getc ( input )) != EOF )
  {
    /* set left to itself as literal flag */
    for ( i = 0 ; i < 256; i++ )
    {
      left[i] = i;
    }

    /* read pair table */
    for ( c = 0 ; ; )
    {
      /* skip range of literal bytes */
      if ( count > 127 )
      {
        c += count -127;
        count = 0;
      }
      if ( c==256 )
      { 
        break;
      }

      /* read pairs, skip right if literal */
      for ( i = 0; i <= count; i++, c++ )
      {
        left[c] = getc(input);
        if ( c != left[c] )
        {
          right[c] = getc(input);
        }
      }
      if (c == 256)
      {
        break;
      }
      count = getc(input);
    }

    /* calculate packed data block size */
    size = 256 * getc(input) + getc(input);

    /* unpack data block */
    for ( i = 0 ; ; )
    {
      /* pop byte from stack or read byte */
      if ( i )
      { 
        c = stack[--i];
      }
      else
      {
        if ( !size--)
        {
          break;
        }
        c = getc(input);
      }

      /* output byte or push pair on stack */
      if ( c == left[c] )
      {
        putc(c, output);
      }
      else
      {
        stack[i++] = right[c];
        stack[i++] = left[c];
      }
    }
  }
}

void main ( int argc, char *argv[] )
{
  FILE *infile, *outfile;

  if ( argc != 3 )
  {
    printf("Usage: expand infile outfile\n");
  }
  else
  {
    if (( infile = fopen(argv[1],"rb"))==NULL)
    {
      printf("Error opening input %s\n",argv[1]);
    }
    else
    {  
      if ((outfile=fopen(argv[2],"wb"))==NULL)
      {
        printf("Error opening output %s\n", argv[2]);
      }
      else
      {
        expand ( infile, outfile );
        fclose ( outfile );
        fclose ( infile );
      }
    }
  }
}

/* end of file */
4

2 に答える 2

1

これは、私が推測するように、あなたがやりたいことをします。関数str_getc()およびはおよびstr_putc()と同等ですputc(int , FILE *)getc(FILE *)

int sCtr = 0, dCtr = 0;
int str_getc(char *str) { return str[sCtr++]; } //char * equivalent of getc()
void str_putc(int c, char *str) { str[dCtr++] = c; } //char * equivalent of putc()

void expand (char *input, char *output)
{
  unsigned char left[256], right[256], stack[30];
  short int c, count, i, size;

  /* unpack each block until end of file */
  while (( count = str_getc ( input )) != -1)
  {
    /* set left to itself as literal flag */
    for ( i = 0 ; i < 256; i++ )
    {
      left[i] = i;
    }

    /* read pair table */
    for ( c = 0 ; ; )
    {
      /* skip range of literal bytes */
      if ( count > 127 )
      {
        c += count -127;
        count = 0;
      }
      if ( c==256 )
      { 
        break;
      }

      /* read pairs, skip right if literal */
      for ( i = 0; i <= count; i++, c++ )
      {
        left[c] = str_getc(input);
        if ( c != left[c] )
        {
          right[c] = str_getc(input);
        }
      }
      if (c == 256)
      {
        break;
      }
      count = str_getc(input);
    }

    /* calculate packed data block size */
    size = 256 * str_getc(input) + str_getc(input);

    /* unpack data block */
    for ( i = 0 ; ; )
    {
      /* pop byte from stack or read byte */
      if ( i )
      { 
        c = stack[--i];
      }
      else
      {
        if ( !size--)
        {
          break;
        }
        c = str_getc(input);
      }

      /* output byte or push pair on stack */
      if ( c == left[c] )
      {
        str_putc(c, output);
      }
      else
      {
        stack[i++] = right[c];
        stack[i++] = left[c];
      }
    }
  }
}


/* end of file */
于 2013-02-04T14:21:34.480 に答える
0

すべての C++ 入力ストリームには、get一度に 1 文字を取得するために使用できる関数があります。また、出力ストリームには対応するput機能があります。

必要な場所を交換するだけです。

もちろん、通常の入出力演算子>><<同様に使用できます。


配列を直接操作したい場合も、ポインターの処理方法を習得すれば簡単です。次に、入力配列と出力配列を関数に渡すだけで、バイトを取得するときは egleft[c] = *input++;を使用し、書き込むときはeg を使用します*output++ = c;


データの保存などに、標準の C++ コンテナーを使用することもできstd::vectorます。この場合、 egstd::vector<char>を使用し、反復子を使用して単一の文字を取得および設定します。


これはすべて実際には非常に基本的なことであり、すぐに習得する必要があります。ポインター、配列、C++標準 I/O 機能、および標準コンテナーの詳細をお読みください。

于 2013-02-04T14:11:48.900 に答える