0

我想使用字节对编码来解压缩字节数组。我拥有的源代码(不是我的)是使用文件流逐字节读取文件。但是,我想解压缩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函数,可用于一次获取一个字符。并且输出流具有相应的put功能。

只需在需要的地方更换。

当然,普通的输入输出操作符>><<可以使用。


如果你想直接处理数组,这也很容易,只要你学会了如何处理指针。然后只需将输入和输出数组传递给函数,并在获取字节时使用 egleft[c] = *input++;并在编写时使用 eg *output++ = c;


您还可以使用标准 C++ 容器std::vector来存储数据。在这种情况下,您使用 eg std::vector<char>,并使用迭代器来获取和设置单个字符。


这实际上都是非常基本的东西,你应该自己快速学习。只需阅读有关指针、数组、C++标准 I/O 功能标准容器的更多信息

于 2013-02-04T14:11:48.900 回答