CSCI 4061 Lab03: Input and Expanding Buffers
- Due: 11:59pm Mon 2/15/2021 on Gradescope
- Approximately 1.00% of total grade
CODE DISTRIBUTION: lab03-code.zip
- Download the code distribution
- See further setup instructions below
CHANGELOG:
- Sun Feb 7 07:46:35 PM CST 2021
- The files
alphabet.txt
andnums.txt
were initially missing fromlab03-code.zip
but have now been added to it.
Table of Contents
1 Rationale
At times programs must deal with an input situation wherein an unknown amount of input must be accepted and stored in a single input pass. This problem is reflected in the following program specification:
Read an arbitrary length string from the user and print its characters back in reverse order.
In such a case, two common constraints are at play:
- The program cannot pre-allocate sufficient space as it may run out for long inputs.
- The input is presented only once so it cannot be counted then read again.
Dynamic data structures like Linked Lists can solve such problems by allocating nodes on demand. However, many problems such as printing in reverse are handled more succinctly with arrays. With arrays, one typically allocates some space initially and reads the input into it. If one runs out of space, allocate a larger space, copy data over to the larger space, and continue reading.
This lab demonstrates a standard technique to do this in which an input array (buffer) is repeatedly expanded to make space for input. This technique will be useful for an upcoming project.
Grading Policy
Credit for this Lab is earned by completing the exercises here and
submitting a Zip of the work to Gradescope. Students are responsible
to check that the results produced locally via make test
are
reflected on Gradescope after submitting their completed
Zip. Successful completion earns 1 Engagement Point.
Lab Exercises are open resource/open collaboration and students are encouraged to coopearte on labs. Students may submit work as groups of up to 5 to Gradescope: one person submits then adds the names of their group members to the submission.
See the full policies in the course syllabus.
2 Codepack
The codepack for this lab is linked at the top of this document. Always download it and unzip/unpack it. It should contain the following files which are briefly described.
File | Use | Description |
---|---|---|
QUESTIONS.txt |
EDIT | Questions to answer: fill in the multiple choice selections in this file. |
print_reverse.c |
Study | C file to study to answer QUIZ questions |
file_reverse.c |
CREATE | Create and complete the program for the CODE portion of the lab |
QUESTIONS.txt.bk |
Backup | Backup copy of the original file to help revert if needed |
Makefile |
Build | Enables make test and make zip |
testy |
Testing | Test running scripts |
test_lab03.org |
Testing | Tests for this lab |
3 QUESTIONS.txt File Contents
Below are the contents of the QUESTIONS.txt
file for the lab.
Follow the instructions in it to complete the QUIZ and CODE questions
for the lab.
__________________ LAB 03 QUESTIONS __________________ Lab Instructions ================ Follow the instructions below to experiment with topics related to this lab. - For sections marked QUIZ, fill in an (X) for the appropriate response in this file. Use the command `make test-quiz' to see if all of your answers are correct. - For sections marked CODE, complete the code indicated. Use the command `make test-code' to check if your code is complete. - DO NOT CHANGE any parts of this file except the QUIZ sections as it may interfere with the tests otherwise. - If your `QUESTIONS.txt' file seems corrupted, restore it by copying over the `QUESTIONS.txt.bk' backup file. - When you complete the exercises, check your answers with `make test' and if all is well, create a zip file with `make zip' and upload it to Gradescope. Ensure that the Autograder there reflects your local results. - IF YOU WORK IN A GROUP only one member needs to submit and then add the names of their group. QUIZ Questions on print_reverse.c ================================= Analyze the `print_reverse.c' application. Compile and run it as shown below ,---- | // DEMO: | > make print_reverse | gcc -Wall -Werror -g -o print_reverse print_reverse.c | | > ./print_reverse # interactive run | hello world # typed input | # press Ctrl-d to end input | dlrow olleh # output from program | | # non-interactive runs via pipes | > printf "0123456789" | ./print_reverse | ... | | > printf "here is everything I have" | ./print_reverse | ... `---- Answer the following Questions about the techniques used in this program. You may need to consult the Manual Page / Documentation on some functions to answer confidently. Location of buf ~~~~~~~~~~~~~~~ The variable `buf' is used to store character data that is read from standard input in `print_reverse'. Which part of memory are these characters stored? - ( ) The Stack: `buf' is declared as a local array near the top of `main()' so exists in `main()''s stack frame. - ( ) The Heap: `buf' points to an array that is `malloc()''d on the heap near the start of main. - ( ) Globals: `buf' is declared outside of any function and is therefore in the Globa/Static/Data portion of program memory. - ( ) Based on the way that `buf' is declared, it is impossible to say where in memory it exists. Expansion of buf ~~~~~~~~~~~~~~~~ The `realloc()' function is used to change the size of the memory area associated with `buf'. According to your read of the code and the manual page for this function, which of the following is returned by `realloc()'? - ( ) It will return `NULL' if it is not possible to find a larger space for `buf' - ( ) It will return the same pointer `buf' if that space can be expanded in place. - ( ) It will return a pointer to a new memory of the requested size where the contents of `buf' have already been copied with the old pointer being automatically `free()''d. - ( ) `realloc()' could return any of these. Resizing Rate ~~~~~~~~~~~~~ Which of the following is used as the "rate" of expansion for the buffer? - ( ) If there is insufficient space in `buf', it is resized to be 1 character larger than its previous size. - ( ) If there is insufficient space in `buf', it is resized to be 10 characters larger than its previous size. - ( ) If there is insufficient space in `buf', it is resized to be 150% of its previous size. - ( ) If there is insufficient space in `buf', it is resized to be 200% of its previous size. Note that expanding by 150% or 200% each iteration leads to an "append item" operation that has an Amortized computation complexity O(1). This approach is often used in data structures such as Python Lists, Java's ArrayList / StringBuffer, or other "dynamic array" data structures. <https://en.wikipedia.org/wiki/Dynamic_array> CODE Adapt to file_reverse.c ============================ Create a new file called `file_reverse.c' and adapt the approach taken in `print_reverse.c' to print the contents of a file in reverse order, character by character. 1. The provided `Makefile' will compile `file_reverse.c' to the program `file_reverse' 2. `file_reverse' should take a command line argument which is the name of a file to print in reverse order. 3. If no command line argument is given, print a usage message and exit with code 1 as demonstrated below. 4. Open the file provided on the command line using the C standard library. Scan data into a character array and expand the array as needed using the techniques demoed in print_reverse. 5. When the entire file has been read in, print the contents in reverse order. 6. Make sure to clean up any memory used through heap allocation or opening files. NOTE: If you are not familiar with how to use `argc / argv' to deal with command line arguments, get help from a colleague or staff member to review this technique. The tests provided via `make test-code' use the files `alphabet.txt' and `nums.txt'. A correctly written program will behave as demonstrated below. ,---- | >> ./file_reverse # run with no args | usage: file_reverse <file> # print usage message | | >> echo $? # show return code | 1 # 1 - error while running program | | >> ./file_reverse alphabet.txt # print alphabet.txt in reverse | | z y x w v u t s r q p o n m l k j i h g f e d c b a | Z Y X W V U T S R Q P O N M L K J I H G F E D C B A | | >> echo $? # check return code | 0 # 0 for no problems | | >> ./file_reverse nums.txt # print nums.txt in reverse | | 52 | 42 | 32 | 22 | 12 | 02 | 91 | 81 | 71 | 61 | 51 | 41 | 31 | 21 | 11 | 01 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 `----
4 Submission
Follow the instructions at the end of Lab01 if you need a refresher on how to upload your completed lab zip to Gradescope.