I have written a program that performs a simple version of Run-Length coding compression on a file. I thought everything worked, but after a closer look at the output from the program, letters after a space are counted 1 too many times. I.e, if the letter 'p' appeared 6 times after a space, the output would say seven appeared. However, it gets the count right for all the other characters. The code that reads in the file and outputs out to another file is below.For simplicity, assume all variables sent to the functions are correct and the files are valid. Any help would be appreciated, as well as general comments, or improvemants that could be made

int Readchar(ifstream& fileread)
{
    char buffer, compare, ch;
    int count, spacesaved;

    buffer = '\0';
    compare = '\0';
    count = 0;
    compare = '\0';
    spacesaved = 0;
    buffer = fileread.get();

    ofstream fileout;
    fileout.open("input.rlc", ios::app);
    if (fileout.good())
    {
        while (fileread.peek() !=EOF)
        {
            if (compare == '\0')
            {
                compare = buffer;
                buffer = fileread.get();
            }

            if (compare == buffer)
            {
                ch = buffer;
                count++;
                buffer = fileread.get();
            }
            else
            {
                if (count  > 3)
                {
                    spacesaved += count - 3;
                }

                Outputstring(buffer, compare, count, ch, fileout);
                compare = '\0';
                buffer = fileread.get();
                count = 0;
                ch = '\0';
            }   
        }
        if (count != 0)
        {
            buffer = '\0';
            Outputstring(buffer, compare,  count, ch, fileout);
        }
    }

    else
    {
        return 1;
    }
    cout << "The total space saved = " << spacesaved << " Byte(s)" << endl;
    fileout.close();
    return 0;
}

//=====================================================================================

int Outputstring(char buffer, char compare, int count, char ch, ofstream& fileout)
{
    char tag;
    int k;

    tag = char(92);
    {
        if (count + 1 < 4 && count != 0)
        {
            for (k = 0; k <=count; k++)
            {
                fileout.put (compare);
                cout.put (compare);
            }
            fileout.put (buffer);
        }

        else if (count == 0)
        {
            fileout.put (compare);
            cout.put (compare);
            fileout.put (buffer);
            cout.put (buffer);
        }


        else
        {
            fileout << tag << ch << count+1 << tag;
            cout << tag << ch << count+1 << tag;
            if (buffer == ' ')
            {
                fileout.put (buffer);
            }
        }
    }
    return 0;
}    

Sample input:pppppllllleeeeeaaaaassssseeeee hhhhheeeeelllllppppp

Expected output: \p5\\l5\e5\\a5\\s5\\e5\ \h5\\e5\\l5\\p5\

Actual output: \p6\\l5\e5\\a5\\s5\\e5\ \h6\\e5\\l5\\p5\

Thanks
Kevin :?:

Edited 3 Years Ago by happygeek: fixed formatting

Kevin,
I have highlighed the problem in red. Move the first buffer = fileread.get() to after you open the file.

int Readchar(ifstream& fileread)
{
  char buffer, compare, ch;
  int count, spacesaved;

  buffer = '\0';
  compare = '\0';
  count = 0;
  compare = '\0';
  spacesaved = 0;

  //buffer = fileread.get();

  ofstream fileout;
  fileout.open("input.rlc", ios::app);
  
  buffer = fileread.get();
  
  if (fileout.good())
  {
    while (fileread.peek() !=EOF)
    {
      if (compare == '\0')
      {
        compare = buffer;
        buffer = fileread.get();
      }

      if (compare == buffer)
      {
        ch = buffer;
        count++;
        buffer = fileread.get();
      }
      else
      {
        if (count > 3)
        {
        spacesaved += count - 3;
        }

        Outputstring(buffer, compare, count, ch, fileout);
        compare = '\0';
        buffer = fileread.get();
        count = 0;
        ch = '\0';
      } 
    }
    if (count != 0)
    {
      buffer = '\0';
      Outputstring(buffer, compare, count, ch, fileout);
    }
  }

  else
  {
    return 1;
  }
  cout << "The total space saved = " << spacesaved << " Byte(s)" << endl;
  fileout.close();
  return 0;
}

//=====================================================================================

int Outputstring(char buffer, char compare, int count, char ch, ofstream& fileout)
{
  char tag;
  int k;

  tag = char(92);
  {
    if (count + 1 < 4 && count != 0)
    {
      for (k = 0; k <=count; k++)
      {
        fileout.put (compare);
        cout.put (compare);
      }
      fileout.put (buffer);
    }

    else if (count == 0)
    {
      fileout.put (compare);
      cout.put (compare);
      fileout.put (buffer);
      cout.put (buffer);
    }


    else
    {
      fileout << tag << ch << count+1 << tag;
      cout << tag << ch << count+1 << tag;
      if (buffer == ' ')
      {
        fileout.put (buffer);
      }
    }
  }
return 0;
}

Kevin,

The previous code change would fix the initial count problem. The count problem after the space could be fixed by removing the following statements from your OuputString() function.

if (buffer == ' ')
      {
        fileout.put (buffer);
      }
This article has been dead for over six months. Start a new discussion instead.