Lab 04: a few pointers

Due Thursday, October 1st, by 4pm


This work continues with exercises similar to the work of Lab 04. We have two new programs to complete, one called sequence.cc that allows you to edit a sequence of integers, and another called rotate.cc that processes a text file containing ASCII art and outputs a new text file containing that art rotated 90 degrees. Both programs rely on the use of a pointer to a struct. And that struct acts as a “cover object” with links to an underlying data structure representing it.

For the sequence program, the underlying data structure is just an array of integers, where the first size items constitute an integer sequence. But, as the program edits the sequence (with user commands insert, append, and remove) that array might need to get resized to have storage for larger sequences. Your jon is to write some of the functions that edit the sequence.

For the rotate program, the underlying data structure is essentially a “two-dimensional array” of characters so as to represent the grid of an ASCII art image. To do this we have a field named image of an asciiArt struct. Its type is

char** image;

Each line of the image is represented as an array of characters, so that means it is a pointer of type char*. Since we want several lines, an image is an array of these char* pointers. It is of type (char*)*, or simply char**. The image field points to an array of arrays.

For this second exercise, you’ll write the code that takes an asciiArt pointer and invents a new asciiArt struct on the heap that is a rotated version of the input image.

I briefly describe each exercise below. The details for the work can also be found by reading the comments within the two source .cc files.

These two programs can be built using the commands make sequence and make rotate, which relies on the provided Makefile (just like we used in lab).


Exercises


Exercise 1. sequence

I’ve written the code for the newSequence, append, and release functions. The first creates a new sequence data structure on the heap and returns a pointer to it. The integer sequence it creates is empty initially, but some space gets allocated to store elements that may get added later. The second uses that extra space to stick a new value onto the end of the sequence. And the last gives back the storage allocated for that data structure to the memory heap.

You are to complete the code of these four functions.

Part 1: output
As the code currently runs, the program outputs a sequence by printing its integers separated by spaces (and with an extra space at the end. Modify this code so that it instead formats the output to use brackets and commas like so:

[47, 37, 18]
[10]
[]

You’ll want to check the size field of S to see how many items are in that sequence, and format the output in those three ways accordingly.

Part 2: resize
The main function builds an empty sequence data structure with capacity to hold two integers using the line:

  sequence* seq = newSequence(2);

Under the covers, an array seq->elements gets built with length 2 within the heap, and seq->size is set to 0. This means that the code can only add two integers to that empty sequence.

But I’ve written append so that, should more than two integers be added by the user, the function calls a procedure resize to allocate a larger array of integers, so that that extra value can then be placed on the end. I’d like you to write the code for resize to make it do that properly.

Roughly expressed, here is what your code needs to do:

  1. Describe a new integer array variable newElements.

  2. Request a new array with room for newCapacity integers.

  3. Copy the data from S->elements into newElements.

  4. Give back the smaller array using delete.

  5. Make the S struct use that new storage.

Part 3: insert
Now finish the code for the other two editing functions. Inserting, like append, may need to resize the array. But, regardless, it should move the sequence data in the array one position to the right, making room to add that new value v at position i.

Part 4: remove This code need not resize the array. It should move the sequence data right of position i to the left one position. This has the effect of “deleting” the i-th value from the sequence.


Exercise 2. rotate

The code in rotate.cc is meant to be a program that reads a file of ASCII art. That might be something like:

 .S_sSSs      sSSs    sSSs   .S_sSSs            sSSs    sSSs  
.SS~YS%%b    d%%SP   d%%SP  .SS~YS%%b          d%%SP   d%%SP  
S%S   `S%b  d%S'    d%S'    S%S   `S%b        d%S'    d%S'    
S%S    S%S  S%S     S%S     S%S    S%S        S%S     S%|     
S%S    d*S  S&S     S&S     S%S    S&S        S&S     S&S     
S&S   .S*S  S&S_Ss  S&S_Ss  S&S    S&S        S&S     Y&Ss    
S&S_sdSSS   S&S~SP  S&S~SP  S&S    S&S        S&S     `S&&S   
S&S~YSY%b   S&S     S&S     S&S    S&S        S&S       `S*S  
S*S   `S%b  S*b     S*b     S*S    d*S        S*b        l*S  
S*S    S%S  S*S.    S*S.    S*S   .S*S        S*S.      .S*P  
S*S    S&S   SSSbs   SSSbs  S*S_sdSSS          SSSbs  sSS*S   
S*S    SSS    YSSP    YSSP  SSS~YSSY            YSSP  YSS'    
SP                                                            
Y

And then, once working, rotates it like so (thanks PATORJK:

YSSSSSSSSSSS..
 P****&&&%%%SS
  SSSSSSSSSSS_
      ~_    ~s
      Ys    YS
      Sd    SS
     `YS.  `%s
  SSSS%SSdSS% 
  S&%%bS**%%b 
  SSSb  SSSb  
              
              
    SSSSSSSd  
   S**&&&&%%ds
  YSSbSSSSSS%S
  SS.  ~_  '%S
  Sb   SS   Ss
  Ps   Ps   P 
              
              
    SSSSSSSd  
   S**&&&&%%ds
  YSSbSSSSSS%S
  SS.  ~_  '%S
  Sb   SS   Ss
  Ps   Ps   P 
              
              
  SSSSSSSSSS..
  S***&&&%%%SS
  SSSSSSSSSSS_
  ~_        ~s
  Ys        YS
  Sd        SS
  SS.      `%s
  YSSdSSSSSS% 
   S**&&&&%%b 
    SSSSSSSb  
              
              
              
              
              
              
              
              
    SSSSSSSd  
   S**&&&&%%ds
  YSSbSSSSSS%S
  SS.      '%S
  Sb        Ss
  Ps        P 
              
              
  Ys   `YSSd  
  SS   S&&%%ds
  SS. `&SS|S%S
  '*SlS&s  '%S
   S***S    Ss
    PSS     P

The files themselves have extra information in their first line, giving their height and width information. A bunch of these .txt files can be found in this repo. For example, you can use the cat command and see

% cat sample.txt
7 10
          
    @###@ 
    #...# 
 %##@...# 
 #......# 
 %######@
 

Two of these are quite large, generated from famous works of art, found at Ian Parberry’s site.

I also have provided a folder full of sample output for the rotate program. I generated each of these with my solution to the exercise. For example, if I typed

% ./rotate sample.txt

I would get a new file named sample-90.txt in my same folder that has the contents

10 7
       
 %#%   
 #.#   
 #.#   
 #.@#@ 
 #...# 
 #...# 
 #...# 
 @###@ 

The code relies on a cool Unix trick that I’ve hinted at in class. The main function can take two parameters (instead of void) named argc and argv. The first of these argc gives the integer count of the number of command-line arguments provided to rotate. Strangely, the command word rotate is couinted as one of the arguments, and so the command rotate sample.txt has a count of 2. The second of these argv is an
“argument vector”, of type char**, so it is an array of an array of characters.

The program, then, gets the filename string sample.txt from the array argv[1].

As the code runs now, it performs no rotation. Instead it just outputs the image contents of the ASCII art file that it reads. Delete those lines, and uncomment the lines at the bottom. Then write and test your code for rotationOf, the function that does all the rotation work. Roughly expressed, that code needs to:

  1. Allocate the asciiArt struct for the rotated image, as pointer outputArt.

  2. Set outputArt->image to be a new array of rows.

  3. Allocate each row outputArt->image[row] as an array of characters.

  4. Set each of the characters outputArt->image[row][column] based on inputArt.

If you want to see similar work, look at readImage which builds an asciiArt struct from the contents of the input file.