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 andstdbool.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 withreadline.
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. (whypos < len-1instead ofpos < 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 filefreadlineis likereadlineexcept it usesgetc(fp)instead ofgetchar()- note the type of
fpisFILE*; it’s a pointer to an object of type FILE. More on that later.