Adv. UNIX: lib/121 Advanced UNIX v Objectives of these slides: –look at some of the less familiar functions in the ANSI C Standard Library Special Topics in Comp. Eng. 1 Semester 2, The Standard Libraries
Adv. UNIX: lib/122 Overview 1. Standard Library Header Files 2. Examining Characters ( ctype.h ) 3. Strings ( string.h ) 4. Maths ( math.h ) 5. Utilities ( stdlib.h ) 6. Timing ( time.h )
Adv. UNIX: lib/ Standard Library Header Files FileContents stdio.h I/O and file operations math.h Mathematical functions string.h String functions ctype.h Character class tests stdlib.h Utility functions continued
Adv. UNIX: lib/124 assert.h Assertions (debugging) setjmp.h Non-local jumps e.g. gotos out of functions signal.h Signal handling errno.h Error handling time.h Time and date functions stdarg.h Variable-length argument lists e.g. as used by scanf(), printf() continued
Adv. UNIX: lib/125 stddef.h Standard definitions e.g. size_t, NULL limits.h Implementation limits e.g. max / min values for different types float.h Floating point constants e.g. precision information locale.h Locality issues (language, etc.) e.g. non-english symbols, money symbol
Adv. UNIX: lib/ Examining Characters () 2. Examining Characters ( ctype.h ) FunctionCharacter Class isalpha(c) Letter isdigit(c) Digit isalnum(c) Letter or digit islower(c) Lower case letter isupper(c) Upper case letter isspace(c) Space, ‘\f’, ‘\n’, ‘\r’, ‘\t’. ‘\v’ tolower(c) Output lower case version toupper(c) Output upper case version ::
Adv. UNIX: lib/127 Example int c; c = getchar(); if (isalpha(c)) c = tolower(c);
Adv. UNIX: lib/ Strings () 3. Strings ( string.h ) 3.1. Common Functions 3.2. Limited Length Functions 3.3. Rarely Used (but Useful) 3.4. String Functions in stdio.h 3.5. Memory Functions
Adv. UNIX: lib/ Common Functions FunctionMeaning char *strcpy(d, s) Copy s to d char *strcat(d, s) Append s onto end of d int strlen(s) Length of s int strcmp(s1, s2) Compare s1 and s2: 0if s1 same as s2 0if s1 > s2
Adv. UNIX: lib/1210 Example char s1[20]; char s2[13] = “ Andrew”; strcpy(s1, “Hello”); /* s1 = “Hello”; is wrong */ strcat(s1, s2); if (strcmp(s1, s2) == 0) printf(“the same\n”);
Adv. UNIX: lib/ Limited Length Functions FunctionMeaning int strncmp(s1, s2, n) Compare at most n chars char *strncpy(d, s, n) Copy at most n chars of s to d char *strncat(d, s, n) Append at most n chars of s to end of d
Adv. UNIX: lib/1212 Example char *s1 = “hello; char *s2 = “help”; if (strncmp(s1, s2, 3) == 0) printf(“First 3 chars the same\n”);
Adv. UNIX: lib/ Rarely Used (but Useful) FunctionMeaning char *strchr(s1,c) Find first c in s1 char *strrchr(s1, c) Find last c in s1 char *strstr(s1, s2) Find s2 in s1 (string search) char *strtok(s1, s2) Tokenise s1 using s2 as delimitor :
Adv. UNIX: lib/1214 Examples char *s = “ char *nm; if ((nm = strrchr(s, ‘/’)) != NULL) printf(“Name: %s\n”, nm+1); /* prints "~ad" */ if (strstr(s, “foo.com”) == NULL) printf(“Not a foo.com address\n”); s nm continued
Adv. UNIX: lib/1215 #define SEP “ “/* space is separator */ char *s=“hello world, jim”; char *token; token = strtok(s, SEP); /* get 1st token */ while (token != NULL) { printf(“token: %s\n”, token); token = strtok(NULL, SEP); /* get next token */ } s is modified
Adv. UNIX: lib/ String Functions in 3.4. String Functions in stdio.h int sprintf(char *str, char *format,...); int sscanf(char *str, char *format,...); Like printf() and scanf() but they use str not stdout / stdin v char s[100]; char *nm = “Andrew”; int age= 38; sprintf(s, “Hello %s, age: %d\n”, nm, age);
Adv. UNIX: lib/ Memory Functions FunctionMeaning int memcmp(s1, s2, n) Compare first n chars of s1 and s2 int memcpy(s1, s2, n) Copy n bytes from s2 to s1 int memmove(s1, s2, n) Like memcpy() but s1 and s2 can overlap
Adv. UNIX: lib/1218 Usage s1 and s2 are of type void * –can be supplied with pointers to anything v Typical use is to manipulate complex data structures efficiently by referring to their location and byte size in memory. For string manipulation use str*** functions.
Adv. UNIX: lib/1219 Example v #define SIZE 100 typedef struct {... } Stude; Stude a[SIZE], b[SIZE]; Stude s1, s2; memcpy(b, a, SIZE*sizeof(Stude)); /* copy a to b */ memcpy(&s2, &s1, sizeof(Stude)); /* copy s1 to s2 */ args must be pointers
Adv. UNIX: lib/ Maths () 4. Maths ( math.h ) v These functions are fairly basic –no complex arithmetic, matrix manipulation Almost all the functions manipulate double s. Your code should use double s: –efficiency, accuracy, portability
Adv. UNIX: lib/1221 Compilation v Some compilers do not link in the maths library automatically. v If you get a load/link error, try: $ gcc -o examp examp.c -lm Refers to the library /usr/lib/libm.so
Adv. UNIX: lib/1222 Error Handling v Maths functions can generate two kinds of errors: –domain errors –range errors v Domain error: caused when a function is given an input argument outside of its range –e.g. sqrt(-1.0) –errno set to EDOM continued
Adv. UNIX: lib/1223 v Range error: caused when a function underflows or overflows –e.g. pow(2, ) –errno set to ERANGE –functions that overflow return HUGE_VAL (with a + or -) –no portable way to detect underflow
Adv. UNIX: lib/ Simple Maths Functions FunctionMeaning sqrt(x) square root of x fabs(x) absolute value of x fmod(x,y) float remainder of x/y ceil(x) ceiling of x –ceil(1.4)== 2.0 ceil(-1.4) == -1.0 floor(x) floor of x –floor(1.4) == 1.0 floor(-1.4) == -2.0
Adv. UNIX: lib/ Trigonometry FunctionMeaning sin(x) sine of x cos(x) cosine of x tan(x) tangent of x asin(x) sin -1 x in range [- /2, /2] acos(x) cos -1 x in range [0, ] atan(x) tan -1 x in range [- /2, /2] atan2(x,y) tan -1 (x/y) in range [- , ] x must be in range [-1,1]
Adv. UNIX: lib/ Exponential FunctionMeaning exp(x) e x pow(x,y) x y log(x) log e x log10(x) log 10 x pow() returns a domain error if x==0 and y<=0 or if x<0 and y is a non-integer log functions return a domain error if x==0 and a range error if x<0
Adv. UNIX: lib/ Utilities () 5. Utilities ( stdlib.h ) v Contains functions for a range of tasks: –simple maths operations on integers –base conversion –dynamic memory allocation –random numbers –sorting / searching arrays –hooks to the system
Adv. UNIX: lib/ Simple Maths Functions FunctionMeaning int abs(int x) absolute value of int x long labs(long n) absolute value of long n div_t div(int x, int y) quotient and remainder of x/y ldiv_t ldiv(long x, long y) same for longs div_t and ldiv_t are structs with two fields –see stdlib.h
Adv. UNIX: lib/ Converting Strings to Numbers FunctionMeaning int atoi(char *s) Convert s to int long atol(char *s) Convert s to long double atof(char *s) Convert s to double The strings must only contain decimal digits (and a sign); atof() knows exponents, fractions v Initial white space is skipped. v The conversion stops when the first illegal character is found.
Adv. UNIX: lib/1230 Example char *s1 = “ 23/7/1976”; char *s2= “23.1e2 is large”; int i; float f; i = atoi(s1);/* i == 23 */ f = atof(s2);/* f == 23.1e2 */
Adv. UNIX: lib/ Dynamic Memory Allocation FunctionMeaning void *malloc(int size) Create size bytes of storage; return pointer to it. void *calloc(int n, int size) Create n*size bytes of storage; return pointer to it. continued
Adv. UNIX: lib/1232 void free(void *addr) Deallocate storage pointed to by addr. void *realloc(void *old-addr, int new-size) Allocate new-size bytes of new storage; move storage at old-addr to new area; return pointer to it.
Adv. UNIX: lib/1233 Example typedef struct { int sno;/* student num */ char name[100]; } Stude; Stude *s; s = (Stude *) malloc(100*sizeof(Stude)); /* s points to 100 element Stude 'array' */ s[0].sno = 1;/* s->sno = 1; */ s = realloc(s, 200*sizeof(Stude)); /* now a 200 element 'array' */
Adv. UNIX: lib/ Random Number FunctionMeaning void srand(unsigned int seed) Set up the random number generator. int rand(void) Return a random number in range 0 to RAND_MAX
Adv. UNIX: lib/1235 Example int n; /* to be assigned values between 1 and 100 */ srand( time(NULL) ); /* standard 'trick' for getting a seed */ n = rand() % ; : n = rand() % ;
Adv. UNIX: lib/ Sorting void qsort(void *arr, int n, int size, ptr_to_fn compare) qsort() uses quicksort to sort any type of array ( arr ) of length n. size is the size of an array element. compare is a pointer to a comparison function; it is used to compare two array elements.
Adv. UNIX: lib/1237 Comparison Type typedef int (*ptr_to_fn)(void *, void *); v The comparison function takes two pointers to the array elements, and returns an integer: < 0when first element < second 0when first == second > 0when first > second
Adv. UNIX: lib/ Sort an integer array #define SIZE 5 int a[SIZE] = {1, 3, 2, 0, 4}, i; qsort(a, SIZE, sizeof(int), icompare); for (i=0; i < SIZE; i++) printf(“%d “, a[i]); continued
Adv. UNIX: lib/1239 int icompare(const void *first, const void *second) /* icompare() gets pointers to the array elements */ { int f, s; f = *(int *) first; s = *(int *) second; return f - s; /* to fit return type */ }
Adv. UNIX: lib/ Sort an array of students typedef struct { int sno;/* student num */ char name[100]; } Stude; #define SIZE 50 Stude s[SIZE]; /*... fill in s[] */ qsort(s, SIZE, sizeof(Stude), scompare); continued
Adv. UNIX: lib/1241 int scompare(const void *first, const void *second) /* scompare() gets pointers to the array elements */ { Stude f, s; f = *(Stude *) first; s = *(Stude *) second; return f.sno - s.sno; }
Adv. UNIX: lib/ Searching Arrays void *bsearch(void *key, void *arr, int n, int size, ptr_to_fn compare) bsearch() uses binary search to search any type of sorted array ( arr ) of length n. size is the size of an array element. Search for an element like the one pointed to by key. Result is a pointer to the found element or NULL. continued
Adv. UNIX: lib/1243 compare is a pointer to a comparison function; –it is used to compare two array elements: the key element and each array element. v Can often use the same comparison function as for sorting.
Adv. UNIX: lib/ Search an integer array #define SIZE 5 int a[SIZE] = {0, 1, 2, 3, 4}; int find = 2; /* search for 2 in a[] */ int *res; res = (int *) bsearch(&find, a, SIZE, sizeof(int), icompare); if (res != NULL) printf(“Found element %d\n”, &res);
Adv. UNIX: lib/ Search for a student First, we must create a student key which contains a student number. But no name is needed. Why? Answer: the scompare function only compares student numbers res will point to the matching student element in s[] (with sno and name values).
Adv. UNIX: lib/1246 #define SIZE 50 Stude s[SIZE], key, *res; /*.... fill in s[] */ /* initialise key */ key.sno = ; res = (Stude *) bsearch(&key, s, SIZE, sizeof(Stude), scompare); if (res != NULL) printf(“Student no, name: %d, %s\n”, res->sno, res->name);
Adv. UNIX: lib/ System Functions FunctionMeaning void exit(int i) Exit program, with i result (use 0 for success, non-0 for failure) int system(char *cmd) Execute OS command string in cmd
Adv. UNIX: lib/1248 Examples char s[100], *fnm = “foo.txt”; sprintf(s, “ls -l %s”, fnm); system(s); /* do ls -l foo.txt */ v Problem: Shell variables are not changed: –system (“cd.. ; ls”); /* correct */ –system(“cd..”); system(“ls”);/* incorrect since no change to cwd after cd */ continued
Adv. UNIX: lib/1249 v The Bourne shell is used to execute the command. system() returns the termination status of the command. v We can read results using temporary files: system(“ls -l > temp”); if ((fp = fopen(“temp”, “r”)) != NULL)... –there is another way: see popen() later
Adv. UNIX: lib/ Access the environment: Access the environment: getenv() Environment variables are shell variables that have been exported (with export in Bourne, setenv in C-Shell) char *getenv(char *env-var); Usage: printf(“Home is %s\n”, getenv(“HOME”));
Adv. UNIX: lib/1251 From the argument From the envp main() argument #include #include int main(int argc, char *argv[], char *envp[]) { int i = 0; /* print out envp[] */ while (envp[i] != NULL) printf(“%s\n”, envp[i++]); return 0; } continued
Adv. UNIX: lib/1252 Each envp[i] contains a string of the form: name=value v Possible output: HOME=/user/ad SHELL=/bin/bash TERM=vt100 USER=ad :
Adv. UNIX: lib/1253 and in popen() and pclose() in stdio.h FILE *popen(char *cmd, char *mode); int pclose(FILE *fp); Use popen() to execute a command and open a pipe into it (or out of it). v The pipe can be manipulated using file I/O commands. continued
Adv. UNIX: lib/1254 v The pipe can be used to send input into the command (or receive output from the command). pclose() closes the pipe and completes the command.
Adv. UNIX: lib/1255 Command input: Command input: wc FILE *fp; int numlines; if ((fp = popen(“wc -l foo.c”, “r”)) == NULL) { perror(“popen() failure of wc”); exit(1); } fscanf(fp, “%d”, &numlines); pclose(fp); program wc -l foo.c fp
Adv. UNIX: lib/1256 Command output: Command output: mail FILE *fp; char *mesg=“hello jim”; if ((fp = popen(“mail -s \”Hi\” “w”)) == NULL) { perror(“popen() failure of mail”); exit(1); } fprintf(fp, “%s\n”, mesg); pclose(fp); program mail -s "Hi" fp
Adv. UNIX: lib/ Timing () 6. Timing ( time.h ) time_t time(time_t *ptr) v Common usage: time_t t; /* usually same as int */ t = time(NULL); /* no. of secs since 1/1/1970 */ Most programs convert time_t values to struct tm or char * for better output. Epoch time
Adv. UNIX: lib/1258 struct tm Look in time.h : struct tm { int tm_sec;/* seconds */ int tm_min;/* minutes */ int tm_hour;/* hours since midnight */ int tm_mday;/* day of month: */ int tm_mon;/* month since January: */ int tm_year;/* years since 1900 */ : }
Adv. UNIX: lib/1259 Conversion Functions struct_tm *localtime(time_t *tptr); char *ctime(time_t *tptr); Usage: time_t t; struct tm tv; t = time(NULL): tv = *localtime(&t); printf(“Day of month: %d\n”, tv.tm_mday); printf(“%s\n”, ctime(&t)); /* the ctime() output is like date */
Adv. UNIX: lib/1260 Processor Time clock_t clock(void) –returns the processor time (number of clock ticks) used by the program since its execution began The number of clock ticks per second is defined in CLOCKS_PER_SEC. v Print execution time in seconds using: –printf(“%f secs running\n”, (double) (clock()/CLOCKS_PER_SEC) );