Lecture C 03
Lecture C 03
Advanced C Topics II
Introduction to the Standard Library
The ISO C Standard
Introduction to the Standard Library
The ISO C Standard
▶ defines a standard library to provide basic functions on every platform and allows portable
programming
▶ consists of about 20 different header files
▶ around 200 function for input/output, basic math, string manipulation, and memory
management
POSIX C Library
▶ important extension to the standard C library
▶ provides more operating system dependent operations
▶ contains functions for networking, inter process communication, threading, and many more
Starting with the C11 standard, threading has also become part of the standard C library.
stdio.h and stdlib.h
Introduction to the Standard Library
stdio.h and stdlib.h
These two headers files provide the basic functionality of the C library. They provide
input/output operations, control statements, and memory management.
The file-io operations will be demonstrated by examples in a separate section.
The input/output functions introduced later in this section contain format strings determining
what is to be read or printed. These format strings contain format specifiers for the
representation of the variables contents. They will be introduced first.
Introduction to the Standard Library
stdio.h and stdlib.h
The [l]type part is what is shown above. The [flags] influence the alignment and
printing of signs. All bracketed specifiers are optional.
Introduction to the Standard Library
stdio.h and stdlib.h
Example
double pi = 3.14159265;
printf("pi = %8.6g\n",pi);
prints:
pi = 3.141593
The printf-function writes a text to the standard output. The fprintf-function is the
equivalent for files, whereas sprintf stores the result in the output string buf. The
return-value is the number of characters written.
stdio.h defines stdout and stderr file descriptors to use fprintf for printing output
and error messages separately.
Introduction to the Standard Library
stdio.h and stdlib.h
▶ scanf-function reads a formatted input from the standard input. This is the keyboard in
most cases. The arguments are pointers to the variables where the values read from the
input are stored.
▶ fscanf-function is the equivalent to read data from a file.
▶ sscanf reads from another string.
▶ fscanf stops reading when either the end of a line, or the end of the file is reached.
▶ sscanf terminates upon reaching the 0-byte.
Introduction to the Standard Library
stdio.h and stdlib.h
The fopen-function opens the file specified by the filename and returns a pointer to the
file stream. mode is a string determining the access to the file:
Mode Meaning Remarks
r open for reading Only possible if the file exists otherwise
NULL is returned.
w create a file for writing If the file already exists the content is
destroyed.
a append data to a file If the file already exists, the new data
is appended to the end. If it does not
exist, the behavior is like ”w”.
fopen returns NULL in case of an error.
Introduction to the Standard Library
stdio.h and stdlib.h
The fclose-function closes a given file stream. Any buffered data is written to the file. The
stream is no longer associated with the file.
The feof-function returns true if the given file stream reached the end of the file otherwise
false is returned.
The perror-function displays the most recent error from the C library. The string s is used as
a prefix to the error message.
Introduction to the Standard Library
stdio.h and stdlib.h
void abort();
void exit(int exit_code);
The atoi-function converts a string to an integer if possible. The atof-function does the
same with a floating point number.
math.h and complex.h
Introduction to the Standard Library
math.h and complex.h
▶ The C99 standard introduces the data types float complex and double complex
for handling complex numbers.
▶ The header file complex.h defines these data types along with the imaginary unit as I
and the following functions for double precision complex arguments and return values.
Introduction to the Standard Library
math.h and complex.h
The string.h-header file contains various functions to manipulate and work with strings.
The important ones are:
size_t strlen(char *s);
The strlen-function returns the length of the string not including the terminating 0
character.
char *strcpy(char *dest, char *src);
▶ Copies a string from src to dest and returns the dest pointer.
▶ dest needs to be a preallocated string with at least strlen(src)+1 elements.
▶ The destination string is not 0-terminated if the source string does not contain the 0-byte
within the length of the destination string.
▶ The behavior in case the destination is to short is unspecified and may depend on the
actual implementation of the compiler.
Introduction to the Standard Library
string.h
The strcat-function appends the string from src to dest and returns the dest pointer
again. dest needs to be a preallocated string with at least
strlen(src)+strlen(dest)+1 elements.
Beside the string operations string.h defines a variety of memory actions like:
The memcpy-function copies n bytes from src to dest and returns the dest pointer again.
dest needs to be preallocated with n bytes. src and dest must not overlap each other.
memmove does the same but allows overlapping. It is slower than memcpy.
The memset-function converts the value ch to an unsigned char and copies it into each
of the first count characters of the location referred by dest.
File I/O
Examples
File I/O
Examples
fopen
opens a specified file in the desired mode. To avoid undefined behavior we have to check if
NULL was returned.
Example
We create file "test.txt" for writing:
FILE *fp;
fp = fopen("test.txt","w");
if ( fp == NULL ) {
perror("can not open test.txt for writing.");
return -1;
}
The fprintf and fscanf functions in the following are only useful for human readable files.
For individual access to binaries we refer to fread, fwrite and other functions from
stdio.h.
Example
The access modes "w" and "a" open files for writing. fprintf is used like printf on this
file:
int x = 10;
double y = 145.1;
fprintf(fp, "x = %d , y = %lg\n", x, y);
File I/O
Examples
The access mode "r" allows fscanf to read data from it. If the feof()-function evaluates
to true, no more data can be read from the file.
Example
We consider a human-readable file with the following layout:
x1 y1
x2 y2
...
File I/O
Examples
Example
The code-snippet to read all values and print them to the screen will be:
FILE *fp;
double x, y;
fp = fopen("test.txt","r");
if ( fp == NULL ) {
perror("can not open test.txt for reading.");
return -1;
}
while (!feof(fp)){
fscanf("%g %g",&x,&y);
printf("x=%g \t y=%g\n",x,y);
}
searches default include path and all directories specified with -I at the gcc command
line for header.h
▶
#include "header.h"
checks the local project directory and can also be used to include other .c-files.
#define
The Preprocessor and Header Files
#define
1.) Constants:
Example
The preprocessor statements:
#define PI 3.14519
#define SQRT2 sqrt(2)
will replace any occurrence of PI with 3.14159 and of SQRT2 with sqrt(2) in the current
source file.
The Preprocessor and Header Files
#define
This is not the desired behavior because the minus in the second part is only applied to z and
not to the whole expression as it was intended.
The Preprocessor and Header Files
#define
Remark
The preprocessor acts stupid on all replacements of define. It does not check whether or not
the resulting code is valid C code. The programmer has to make sure that the define
statements are extended to correct C code.
#ifdef
The Preprocessor and Header Files
#ifdef
ifdef-directive
▶ allows conditional compiling of the source code
▶ works like the if-else construct, but is evaluated by the preprocessor at compile time
#ifdef PREPROCESSOR_DEFINE
// Code compilied if PREPROCESSOR_DEFINE exitsts
#else
// Code compiled otherwise
#endif
This technique is used to handle different environment situations in a single source file
The Preprocessor and Header Files
#ifdef
Example
In order to debug a program easily somebody defined an INFO-macro which prints the given
parameter to the screen. In the final version of the program this is not necessary. However,
removing all outputs in the code may be unwanted to be able to insert them again for later
debugging purposes:
#ifdef DEBUG
#define INFO(X) printf(X)
#else
#define INFO(X)
#endif
The #ifndef statements is the opposite of #ifdef. It simply negates the condition of the
#ifdef statement.
Header-Files
The Preprocessor and Header Files
Header-Files
Header-Files
▶ tell the compiler which functions, data-structures, and constants exist in other source files
▶ compiler can only check the function headers and the calling sequence in the current file
▶ similar to a normal source file but consist only of definitions
▶ come without any implementation
Cyclic inclusions should be avoided using the preprocessor commands #define and #ifndef
The Preprocessor and Header Files
Header-Files
Example
exfct.c implements the function something:
#include <math.h> // for sqrt
#include "exfct.h" // Ensure that the function header
// fits to the one from exfct.h
double something(double x, double y, double z){
return sqrt(x*x+y*y+z+z*z);
}
The Preprocessor and Header Files
Header-Files
Example
exfct.h contains:
▶ the function header (its signature)
▶ a preprocessor trick preventing double inclusion in one file:
#ifndef EXFCT_H
#define EXFCT_H
double something(double x, double y, double z);
#endif
The main program can now include the header and knows how the function something is
called correctly.
Makefiles
Make
Makefiles
Make
Makefile
▶ works as a simple dependency tree
▶ compiles the files that are outdated in the order they depend on each other
▶ consists of so called targets, which may depend on each other
The indentation in front of the commands must be a <tab> and not spaces!
Makefiles
Make
Makefile
▶ works as a simple dependency tree
▶ compiles the files that are outdated in the order they depend on each other
▶ consists of so called targets, which may depend on each other
The targetname should be equal to or closely related to the output file generated by the
commands.
Makefiles
Make
Makefile
▶ works as a simple dependency tree
▶ compiles the files that are outdated in the order they depend on each other
▶ consists of so called targets, which may depend on each other
dependencies is a space separated list of other targets that need to be compiled prior to the
target or names of files which need to exist.
Makefiles
Make
Example
Consider a small software project consisting of main.c, file1.c and file1.h. A makefile
to create the final program prog looks like:
prog: main.c file1.c file1.h
gcc -c main.c
gcc -c file1.c
gcc -o prog main.o file1.o
Variables
▶ make supports definition of variables
▶ often they contain lists of files
▶ or they are used to inherit compiler settings from include files
A variable is set by
VARNAME=VALUE
and accessed with $(VARNAME). To change the extension of all files listed in a variable the
substitute command is used. The syntax is
NEWVAR = ${OLDVAR:.old=.new}
This replaces the extension of every file ending with .old in OLDVAR to .new and stores the
list to NEWVAR. This is normally used to create a list of object files form the list of source files.
Makefiles
Make
Suffix Rules
▶ avoid separate rules for all input files
▶ create targets for all files matching the suffix
▶ apply to all files that have not been processed by a separate rule before
▶ Two placeholders exist referring to the input and the output filenames. The input file is
referred to using $< and the output file using $@.
▶ Finally, we define a clean up target. The target clean removes all object files or
intermediate outputs. Because this target does not produce an output file and does not
depend on a file called clean, it needs to be declared as .PHONY target.
▶ Other techniques extend the make file such as automatic dependency creation using the
GCC compiler, pattern rules as a generalization of the suffix rules, include statements, if
directives, and many more.
▶ Other tools like CMake2 or the GNU Autotools3 provide high level scripting languages to
create complex makefiles automatically.
2 https://www.cmake.org
3 https://en.wikipedia.org/wiki/GNU_build_system
Makefiles
Make
Example
SRC=main.c file1.c
OUTPUT=prog
CC=gcc
CFLAGS= -O2
OBJECTS=${SRC:.c=.o}
.PHONY: clean
.SUFFIXES: .c .o
$(OUTPUT): $(OBJECTS)
$(CC) -o $(OUTPUT) $(CFLAGS) $(OBJECTS)
.c.o:
$(CC) -c -o $@ $(CFLAGS) $<
clean:
rm -f $(OBJECTS)