Exercise 18: Reallocate Memory

For this assignment you will create a program similar to the example code from the video about realloc(), but instead of printing all of the integers that were read from standard input, you will print a “slice” of those integers, or only the integers between two given indexes. Write your program in the provided file slice_stdin.c.

The indexes are to be given as command line arguments, and you are to print the integers from the given first index to the given last index, one integer per line. As with the example program, you should read integers from standard input using scanf(), and stop reading when you either get to EOF or input is encountered that is not an integer.

So if standard input contains 4 5 6 7 8 done, then your program should read the integers 4, 5, 6, 7, and 8 into an array. If the given first index is 1 and the given last index is 3, then your program should print the following:

5
6
7

Input Validation

Your program must validate the command line arguments. For this assignment you do not need to worry about looking at each character of each command line argument to make sure they are all digits like you did with the roll dice project, you may simply use atoi() to convert them to integers and check the values (remember you need stdlib.h for this). Print an error message and return specific non-zero exit codes for the following conditions:

Note that normally size_t is a good type to use to store indexes. However, because you need to check for negative indexes and because size_t is an unsigned type, you will either need to use int variables to store the indexes after using atoi() to convert the string arguments to integers when you check to see if they are negative, or check the return value of atoi() directly in an if statement, and then assign to a size_t later, knowing that the integer will be non-negative.

Creating and Resizing the Array

You must use malloc() to create the array that will store the input, and realloc() to resize the array as needed. Use the same strategy as in the example, where the array is initially big enough to hold only one integer, and the capacity doubles whenever the array is full. After reading all the input, resize the array to be exactly the right size to hold all the input. Free the array when you are done with it.

Example Output

Below are a number of examples of how your program should behave.

./slice
Usage: ./slice <first index> <last index>

./slice 1 3
20 30 40 50 60 70 done
30
40
50

./slice 10 3
The first index cannot be greater than the last index

./slice -5 10
Indexes must be non-negative

./slice 10 20
1 2 3 done
The first index is too large

The input can also come from a file. If numbers.txt contains 6 10 100 -30 15 45 then you can do this:

./slice 0 3 < numbers.txt
6
10
100
-30

To test your program with a large number of input numbers, you can use the seq command line utility. If you run seq 100000, it will print the numbers 1 through 100000. You can use the standard output of seq as the standard input for your program by using the | character, which is also called a pipe. Below I pipe the standard output of seq 100000 to the standard input of my program to take a slice:

seq 100000 | ./slice 10000 10005
10001
10002
10003
10004
10005
10006

Local Testing

You can run the GitHub testing locally with the command:

make gh-test-slice

THE LAST TEST IS THE LARGE RANGE OF NUMBERS AND IT COULD TAKE A BIT OF TIME TO COMPLETE.

I’ve made this the last test so if you are passing everything else, you are likely to pass this test as well and only need to run it once.

Submission

Push your code to GitHub. For full credit, the tests must pass, you must follow the requirements for using realloc() as stated above, and you must follow proper style.

Grading

Your grade for this assignment will be out out of 10 points: