Lecture Extra - Additional examples
These examples are meant to complement the lecture.
Three examples
- names0.c: (read a list of names into an array and print it back out)
- names1.c: (pulls readline()out to readline.c and readline.h)
- names2.c: (read from a file, if provided, instead of from stdin); leverages freadline.c and freadline.h
Bonus example: strings.c: how C strings work. We will not get to explore this example - but it is well worth playing with it on your own.
Key concepts
names0.c: (read a list of student names into an array and print them back out)
names0.c
preamble
- booldata type and- stdbool.h
main
- the notion of char*representing a string, and that strings are arrays of characters
- use of constfor values that will never change.
- declaration of namesas two-dimensional array; think of it as a one-dimensional array of strings.
- forloop with three parts:- 1: n=0initializer
- 2: two reasons to end (namesis full, or file reaches EOF)
- 3: empty
 
- 1: 
- printfloop does not include- \nbecause each name includes a newline character, per the contract with- readline.
readline
- we could use gets(s)to read a line from stdin, but it can easily overwrite the space allocated to strings
- we could use fgets(s, len, stdin), which will not overwrite a stringsof sizelen, but may not read a whole line from the input.
- let’s write our own readlinefunction instead.
- detailed comment describing the contract between caller and the function.
- whileloop that runs until EOF or buffer is full. (why- pos < len-1instead of- pos < len?)
- use of pos++notation to step through array.
- need to null-terminate the string with \0
- returnfrom inside the loop.
- need to strip excess characters from an over-length line, until we reach EOF or newline.
names1.c
names1.c: (pulls out readline() to readline.c and readline.h)
names1.c
- #include "readline.h"- note the quotes, rather than brackets. this means it will be sought in the the current directory, rather than in a standard place where C libraries live.
readline.h - textually included in names1.c at the point where #include was used.
- use of externon the prototype to indicate this function will be provided in another .c file
- readlineheader comment is here, not in the .c file, so it is easily readable by users of this function.
- use of #ifndefto protect against repeated inclusion of this file
#ifndef __READLINE_H__
#define __READLINE_H__
...
#endif //  __READLINE_H__
readline.c
- also #include "readline.h"- not strictly necessary in this case, but it gives the compiler a chance to check that prototype (from .h file) matches the definition (from .c file).
names2.c
names2.c: (read from a file, if provided, instead of from stdin); leverages freadline.c and freadline.h
- maintakes arguments
- code checks arguments for validity
- use of fopento open a file for reading ("r")
- error messages printed to stderrwithfprintf
- fclose(fp)later called to close the file
- freadlineis like- readlineexcept it uses- getc(fp)instead of- getchar()
- note the type of fpisFILE*; it’s a pointer to an object of type FILE. More on that later.