# Introduction
*Before beginning:* Read this [lab tutorial](lab-tutorial.pdf);
it has some useful tips for programming in the C environment.
This project is a simple warm-up to get you used to how this whole
project thing will go. It also serves to get you into the mindset of a C
programmer, something you will become quite familiar with over the next few
months. Good luck!
You will write a simple program called `reverse`. This program should
be invoked in one of the following ways:
```sh
prompt> ./reverse
prompt> ./reverse input.txt
prompt> ./reverse input.txt output.txt
```
The above line means the users typed in the name of the reversing program
`reverse` (the `./` in front of it simply refers to the current working
directory (called dot, referred to as `.`) and the slash (`/`) is a separator;
thus, in this directory, look for a program named `reverse`) and gave it
either no command-line arguments, one command-line argument (an input file,
`input.txt`), or two command-line arguments (an input file and an output file
`output.txt`).
An input file might look like this:
```
hello
this
is
a file
```
The goal of the reversing program is to read in the data from the specified
input file and reverse it; thus, the lines should be printed out in the reverse
order of the input stream. Thus, for the aforementioned example, the output
should be:
```
a file
is
this
hello
```
The different ways to invoke the file (as above) all correspond to slightly
different ways of using this simple new Unix utility. For example, when
invoked with two command-line arguments, the program should read from the
input file the user supplies and write the reversed version of said file to
the output file the user supplies.
When invoked with just one command-line argument, the user supplies the input
file, but the file should be printed to the screen. In Unix-based systems,
printing to the screen is the same as writing to a special file known as
*standard output*, or `stdout` for short.
Finally, when invoked without any arguments, your reversing program should
read from *standard input* (`stdin`), which is the input that a user types in,
and write to standard output (i.e., the screen).
Sounds easy, right? It should. But there are a few details...
# Details
## Assumptions and Errors
- *Input is the same as output:* If the input file and output file are the
same file, you should print out an error message "Input and output file must
differ" and exit with return code 1.
- *String length:* You may not assume anything about how long a line should
be. Thus, you may have to read in a very long input line...
- *File length:* You may not assume anything about the length of the
file, i.e., it may be *VERY* long.
- *Invalid files:* If the user specifies an input file or output file, and
for some reason, when you try to open said file (e.g., `input.txt`) and
fail, you should print out the following exact error message: `error:
cannot open file 'input.txt'` and then exit with return code 1 (i.e., call
`exit(1);`).
- *Malloc fails:* If you call `malloc()` to allocate some memory, and
malloc fails, you should print the error message `malloc failed` and exit
with return code 1.
- *Too many arguments passed to program:* If the user runs `reverse`
with too many arguments, print `usage: reverse