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.txtandnums.txtwere initially missing fromlab03-code.zipbut 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.