Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Strange output when expanding a RLE string in C

I have been banging my head about this for days. I have to make a program for University that used Run Length Encoding to either compress or decompress an ASCII art file depending on the first character in the string a ‘C’ or an ‘E’. The compression part is working like a charm. BUT the expansion is just ever so slightly off on 2/60 lines. And I just cannot figure out why. Belo is the code for my expand() function and main() I didn’t include my compress() because it is working correctly

I have tried to check for memory leaks/ buffer overflows but to no avail, As far as I know Im freeing memory correctly. and making sure that strings from a new line are not being read as the previous.

ASCII Art input:
(E for expansion)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

E
   20###05
   12###07   06#**#!!###03
   11#**#!!!04##   03#***04#!!!04#
   10#***04###03!!!03#  #***05#!!!04#
   10#***07#!!!03# #***06#!!!04#
   10#***09#!###03!*!*!*#!!!05#   08--
   10#!*!*!*!*!*!#!###0A!!!04#   06/_
   10###0B!##!!!0A#!!!03#   05//__
   0D###03!!!0B#!!!0D#!!!03###04///03  \
   03\   07##!#!!!0B#!!!0F#!!!07#
   03_\   04##!!#!!!0B#!!!0B###06!!!07*#
   04\\  ##!!#!!!0C#!!!04###07   05#!!!06***03#
  ___03\\#!!!03###13***05   07#...03!!***05#
 /   03\#!!!03.#   07***05 #   05***03   08#...04***07#
   05#*...04#   08***03   03#   0E#...07***05#
   04#**...05##   0A***05   0A##...08!!***04#
   04#!...08##   07***07###09...06#...03!!!05*#
   03#!...0B###07.***05...0F#.#..!!!04**#
  #*...05##...0D#..#...0F#...03#.!!***04#
  #*...04#.#...0C#...04#...0C##...06!***05#
  #*...07##...07###03...06###03...08#...07!!!03***04#
  #*...09###07...06!!...04###08...07!!!05***03#
   03#!!!03...11!!!08...0D!!!03***07#
   04#!!!04...0C!!!1B***06#
   05#***07!!!1C***03!!!04***05#
   06#***06!!!19***08!!***04#
   07##***05!!!15#***0D###03
   09##***04!!!15###03***06###04
   0B###04!!!18###06!#
   0F#!!!1E*#
   0F#!!!1D***03##
   0E#!!!1D***06#
   0D#!!!1D***07#
   0C#!!!20***05#
   0B#!!!23**#
   0A#!!!27##
   09#!!!29*##
   08#!!!2B***03#
   08#!!!21###04!!!06***04##
   07#!!!1F###03***04##!!!04***06##
   07#!!!1D##**!!***05#!!!03***08#
   07#!!!08#!!!0B#!!!07#***03!!!04***03!!!04***0A#
   06#!!!0A#!!!09#!!!07#***04!!!05*!!!0A***05#
   06#!!!0B#!!!07#!!!07#*!!***03!!!11***03#
   06#!!!0C#!!!06#!!!06#*!!!05*!!!0F***05#
   06#!!!0C#!!!06#!!!05#***03!!!11***08#
   05#!!!0D#!!!06#!!!05#***04!!!0E***0A#
   05#!!!0D#!!!06#!!!05#***05!!!0E***09#
   05#!!!0D#!!!06#!!!05#***03!!!11***08##
   04##!!!0D#!!!06#!!!05#*!!!15***05#!*##
   03#!#!!!08###06!!!06#!!!05#**!!!0A###09!!!04*#!!**##
  #!#!#!!!06#!!!0C#!!!05#***03!!!05###04***06!!!03###07!!**#
 #!#!!##!!!04#!!!0B###0C*!!!03#***08!!!0F**#
 #!#!!#!#!!#!!!03#!!!07#!!!0F#***0B!!!0F#
 #!#!!!03#!#!#!!#!!!07#!!!04#!!!04#!!!05#***0A!!!0F**#
 #!!#!!!03#!##!!#!!!06#!!!04#!!!04#!!!06#***0C!!!0A***04#
  ###09 ###0A!!!04#!!!04#!!!06#***0A!!!0C***03#
   16###11***0C!!!0A**#
   26#***0A!!!05###09
   27###0F

Expected output ASCII art:

                                #####
                  #######      #**#!!###
                 #**#!!!!##   #****#!!!!#
                #****###!!!#  #*****#!!!!#
                #*******#!!!# #******#!!!!#
                #*********#!###!*!*!*#!!!!!#        --
                #!*!*!*!*!*!#!##########!!!!#      /_
                ###########!##!!!!!!!!!!#!!!#     //__
             ###!!!!!!!!!!!#!!!!!!!!!!!!!#!!!####///  \
   \       ##!#!!!!!!!!!!!#!!!!!!!!!!!!!!!#!!!!!!!#
   _\    ##!!#!!!!!!!!!!!#!!!!!!!!!!!######!!!!!!!*#
    \\  ##!!#!!!!!!!!!!!!#!!!!#######     #!!!!!!***#
  ___\\#!!!###################*****       #...!!*****#
 /   \#!!!.#       ***** #     ***        #....*******#
     #*....#        ***   #              #.......*****#
    #**.....##          *****          ##........!!****#
    #!........##       *******#########......#...!!!!!*#
   #!...........#######.*****...............#.#..!!!!**#
  #*.....##.............#..#...............#...#.!!****#
  #*....#.#............#....#............##......!*****#
  #*.......##.......###......###........#.......!!!****#
  #*.........#######......!!....########.......!!!!!***#
   #!!!.................!!!!!!!!.............!!!*******#
    #!!!!............!!!!!!!!!!!!!!!!!!!!!!!!!!!******#
     #*******!!!!!!!!!!!!!!!!!!!!!!!!!!!!***!!!!*****#
      #******!!!!!!!!!!!!!!!!!!!!!!!!!********!!****#
       ##*****!!!!!!!!!!!!!!!!!!!!!#*************###
         ##****!!!!!!!!!!!!!!!!!!!!!###******####
           ####!!!!!!!!!!!!!!!!!!!!!!!!######!#
               #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*#
               #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!***##
              #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!******#
             #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*******#
            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*****#
           #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!**#
          #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!##
         #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*##
        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!***#
        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!####!!!!!!****##
       #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!###****##!!!!******##
       #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!##**!!*****#!!!********#
       #!!!!!!!!#!!!!!!!!!!!#!!!!!!!#***!!!!***!!!!**********#
      #!!!!!!!!!!#!!!!!!!!!#!!!!!!!#****!!!!!*!!!!!!!!!!*****#
      #!!!!!!!!!!!#!!!!!!!#!!!!!!!#*!!***!!!!!!!!!!!!!!!!!***#
      #!!!!!!!!!!!!#!!!!!!#!!!!!!#*!!!!!*!!!!!!!!!!!!!!!*****#
      #!!!!!!!!!!!!#!!!!!!#!!!!!#***!!!!!!!!!!!!!!!!!********#
     #!!!!!!!!!!!!!#!!!!!!#!!!!!#****!!!!!!!!!!!!!!**********#
     #!!!!!!!!!!!!!#!!!!!!#!!!!!#*****!!!!!!!!!!!!!!*********#
     #!!!!!!!!!!!!!#!!!!!!#!!!!!#***!!!!!!!!!!!!!!!!!********##
    ##!!!!!!!!!!!!!#!!!!!!#!!!!!#*!!!!!!!!!!!!!!!!!!!!!*****#!*##
   #!#!!!!!!!!######!!!!!!#!!!!!#**!!!!!!!!!!#########!!!!*#!!**##
  #!#!#!!!!!!#!!!!!!!!!!!!#!!!!!#***!!!!!####******!!!#######!!**#
 #!#!!##!!!!#!!!!!!!!!!!############*!!!#********!!!!!!!!!!!!!!!**#
 #!#!!#!#!!#!!!#!!!!!!!#!!!!!!!!!!!!!!!#***********!!!!!!!!!!!!!!!#
 #!#!!!#!#!#!!#!!!!!!!#!!!!#!!!!#!!!!!#**********!!!!!!!!!!!!!!!**#
 #!!#!!!#!##!!#!!!!!!#!!!!#!!!!#!!!!!!#************!!!!!!!!!!****#
  ######### ##########!!!!#!!!!#!!!!!!#**********!!!!!!!!!!!!***#
                      #################************!!!!!!!!!!**#
                                      #**********!!!!!#########
                                       ###############

Actual output(Difference is surrounded by ((eg))

       (((###############¶ ¶¶¶¶¶¶                         #####)))
                  #######      #**#!!###
                 #**#!!!!##   #****#!!!!#
                #****###!!!#  #*****#!!!!#
                #*******#!!!# #******#!!!!#
                #*********#!###!*!*!*#!!!!!#        --
                #!*!*!*!*!*!#!##########!!!!#      /_
                ###########!##!!!!!!!!!!#!!!#     //__
             ###!!!!!!!!!!!#!!!!!!!!!!!!!#!!!####///  \
   \       ##!#!!!!!!!!!!!#!!!!!!!!!!!!!!!#!!!!!!!#
   _\    ##!!#!!!!!!!!!!!#!!!!!!!!!!!######!!!!!!!*#
    \\  ##!!#!!!!!!!!!!!!#!!!!#######     #!!!!!!***#
  ___\\#!!!###################*****       #...!!*****#
 /   \#!!!.#       ***** #     ***        #....*******#
     #*....#        ***   #              #.......*****#
    #**.....##          *****          ##........!!****#
    #!........##       *******#########......#...!!!!!*#
   #!...........#######.*****...............#.#..!!!!**#
  #*.....##.............#..#...............#...#.!!****#
  #*....#.#............#....#............##......!*****#
  #*.......##.......###......###........#.......!!!****#
  #*.........#######......!!....########.......!!!!!***#
   #!!!.................!!!!!!!!.............!!!*******#
    #!!!!............!!!!!!!!!!!!!!!!!!!!!!!!!!!******#
     #*******!!!!!!!!!!!!!!!!!!!!!!!!!!!!***!!!!*****#
      #******!!!!!!!!!!!!!!!!!!!!!!!!!********!!****#
       ##*****!!!!!!!!!!!!!!!!!!!!!#*************###
         ##****!!!!!!!!!!!!!!!!!!!!!###******####
           ####!!!!!!!!!!!!!!!!!!!!!!!!######!#
               #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*#
               #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!***##
              #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!******#
             #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*******#
            #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*****#
           #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!**#
          #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!##
         #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*##
        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!***#
        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!####!!!!!!****##
       #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!###****##!!!!******##
       #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!##**!!*****#!!!********#
       #!!!!!!!!#!!!!!!!!!!!#!!!!!!!#***!!!!***!!!!**********#
      #!!!!!!!!!!#!!!!!!!!!#!!!!!!!#****!!!!!*!!!!!!!!!!*****#
      #!!!!!!!!!!!#!!!!!!!#!!!!!!!#*!!***!!!!!!!!!!!!!!!!!***#
      #!!!!!!!!!!!!#!!!!!!#!!!!!!#*!!!!!*!!!!!!!!!!!!!!!*****#
      #!!!!!!!!!!!!#!!!!!!#!!!!!#***!!!!!!!!!!!!!!!!!********#
     #!!!!!!!!!!!!!#!!!!!!#!!!!!#****!!!!!!!!!!!!!!**********#
     #!!!!!!!!!!!!!#!!!!!!#!!!!!#*****!!!!!!!!!!!!!!*********#
     #!!!!!!!!!!!!!#!!!!!!#!!!!!#***!!!!!!!!!!!!!!!!!********##
    ##!!!!!!!!!!!!!#!!!!!!#!!!!!#*!!!!!!!!!!!!!!!!!!!!!*****#!*##
   #!#!!!!!!!!######!!!!!!#!!!!!#**!!!!!!!!!!#########!!!!*#!!**##
((!!!!***#)) #!#!#!!!!!!#!!!!!!!!!!!!#!!!!!#***!!!!!####******!!!#######!!**#
 #!#!!##!!!!#!!!!!!!!!!!############*!!!#********!!!!!!!!!!!!!!!**#
 #!#!!#!#!!#!!!#!!!!!!!#!!!!!!!!!!!!!!!#***********!!!!!!!!!!!!!!!#
 #!#!!!#!#!#!!#!!!!!!!#!!!!#!!!!#!!!!!#**********!!!!!!!!!!!!!!!**#
 #!!#!!!#!##!!#!!!!!!#!!!!#!!!!#!!!!!!#************!!!!!!!!!!****#
  ######### ##########!!!!#!!!!#!!!!!!#**********!!!!!!!!!!!!***#
                      #################************!!!!!!!!!!**#
                                      #**********!!!!!#########
                                       ###############((¶))

And this is my expand() and main() method:

// Function to expand a compressed string
char* expand(const char *input) {
    // Allocate memory for the output string
    char *output = (char *)malloc(2 * strlen(input) + 1);
    char *result = output; // Pointer to store the output
    char currentChar;
    int count;
    char hexCount[3];

    // Iterate through the input string
    for (size_t i = 0; i < strlen(input); i++) {
        currentChar = input[i];
        // Check if a character of the input has a hex digit one and 2 places in front of it -- meaning it's been compressed
        if (i + 4 < strlen(input) && input[i + 1] == currentChar && input[i + 2] == currentChar && isxdigit(input[i + 3]) && isxdigit(input[i + 4])) {
            // Copy the hex number from compressed string into the hexCount buffer
            strncpy(hexCount, &input[i + 3], 2);
            hexCount[2] = '\0';

            // Convert the hex count to decimal
            count = strtol(hexCount, NULL, 16);

            // Append the character 'count' times to the output
            for (int j = 0; j < count; j++) {
                strncat(output, &currentChar, 1);
            }
            i += 4;
        } else {
            // Append the character to the output
            strncat(output, &currentChar, 1);
        }
    }
    return result;
}

int main() {
    // Read each line from stdin, apply the compress/expand function
    char line[MAX_LINE_LEN];
    fgets(line, sizeof(line), stdin);  // Consume the newline after reading excomp
    char excomp = line[0];
    int lineNum = 0;
    if (excomp == 'C') {
        while (fgets(line, sizeof(line), stdin) != NULL) {
            // Remove the newline character
            line[strcspn(line, "\n")] = '\0';

            char *modifiedLine = compress(line);
            char *finalLine = modifiedLine;

            // Print the modified line to the command line
            printf("%s\n", finalLine);

            // Free the memory allocated by FUNCTION
            free(modifiedLine);
        }

        
    } else if (excomp == 'E') {
        while (fgets(line, sizeof(line), stdin) != NULL) {
            // Remove the newline character
            line[strcspn(line, "\n")] = '\0';

            char *modifiedLine = expand(line);
            char *finalLine = modifiedLine;

            // Print the modified line to the command line
            printf("%s\n", finalLine);

            // Free the memory allocated by FUNCTION
            free(modifiedLine);
        }

    }


    return 0;
}

Thank you so much for any help, Cheers!!

>Solution :

Firstly, the allocation

char *output = (char *)malloc(2 * strlen(input) + 1);

is wrong. For example, a short input

###20

can be expanded into a long output (more than double of the input length)

################################

You have to allocate enough space. For example:

char *output = malloc(MAX_LINE_LEN + 1);

Also note that casting results of malloc() family is considered as a bad practice.

Secondly, you have to initialize the allocated buffer before using strncat().
Otherwise, undefined behavior will be invoked by using values in buffer allocated via malloc() and not initialized.
You can do this by adding

output[0] = '\0';

before the for loop in the function expand.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading