<<

C PROGRAMMING

6996 Columbia Gateway Drive Suite 100 Columbia, MD 21046 Tel: 443­692­6600 http://www.umbctraining.com

C PROGRAMMING

Course # TCPRG3000 Rev. 10/14/2016

©2016 UMBC Training Centers 1 C PROGRAMMING

This Page Intentionally Left Blank

©2016 UMBC Training Centers 2 C PROGRAMMING

Course Objectives

● At the conclusion of this course, students will be able to: ⏵ Write non­trivial C programs. ⏵ Use data types appropriate to specific programming problems. ⏵ Utilize the modular features of the C languages. ⏵ Demonstrate efficiency and readability. ⏵ Use the various constructs. ⏵ Create and traverse arrays. ⏵ Utilize pointers to efficiently solve problems. ⏵ Create and use structures to implement new data types. ⏵ Use functions from the C runtime .

©2016 UMBC Training Centers 3 C PROGRAMMING

This Page Intentionally Left Blank

©2016 UMBC Training Centers 4 C PROGRAMMING

Table of Contents

Chapter 1: Getting Started...... 9 What is C?...... 10 Sample Program...... 11 Components of a C Program...... 13 Data Types...... 14 Variables...... 16 Printing and Initializing Variables...... 17 Arrays...... 19 Compiling and Executing a C Program...... 21 Chapter 2: Functions and Operators...... 25 Functions...... 26 Elementary Operators...... 28 Assignment Operators...... 29 Increment and Decrement Operators...... 30 Number of Operands...... 32 Conditional Operator...... 33 Chapter 3: Control Flow Constructs...... 39 Conditionals...... 40 if...... 41 if­else­if...... 43 switch...... 45 Loops...... 46 while...... 47 for...... 48 do­while...... 49 Endless Loops...... 50 break and continue...... 51 switch...... 53 Chapter 4: The C ...... 61 #define...... 62 Preprocessor Macros...... 64 #include...... 66 Conditional Compilation...... 67 #ifndef...... 69 Chapter 5: Simple I/O...... 73 Character I/O...... 74 End of File...... 76 Simple I/O Examples...... 78 Simple I/O Redirection...... 80 I/O with Character Arrays...... 81 ©2016 UMBC Training Centers 5 C PROGRAMMING Chapter 6: More on Functions...... 85 Introduction...... 86 Function Declarations...... 87 Returning a Value or Not...... 88 Function Prototypes...... 89 Arguments and Parameters...... 91 Organization of C Source Files...... 93 Extended Example...... 94 The getaline Function...... 96 The mystrcmp Function...... 97 The check Function...... 98 The myatoi Function...... 99 The average Function...... 100 Summary...... 101 Chapter 7: Strings...... 105 Fundamental Concepts...... 106 Aggregate Operations...... 108 String Functions...... 110 String Functions Example...... 112 Chapter 8: Pointers...... 115 Fundamental Concepts...... 116 Pointer Operators and Operations...... 118 Changing an Argument with a Function Call...... 119 Pointer Arithmetic...... 121 Array Traversal...... 123 String Functions with Pointers...... 127 Pointer Difference...... 129 Prototypes for String Functions...... 130 Relationship Between an Array and a Pointer...... 131 The Pointer Notation *p++...... 132 Chapter 9: Structures...... 137 Fundamental Concepts...... 138 Describing a Structure...... 139 Creating Structures...... 140 Operations on Structures...... 141 Functions Returning Structures...... 142 Passing Structures to Functions...... 144 Pointers to Structures...... 145 Array of Structures...... 149 Functions Returning a Pointer to a Structure...... 151 Chapter 10: File I/O...... 155 System Calls vs. Library Calls...... 156 Opening Disk Files...... 157

©2016 UMBC Training Centers 6 C PROGRAMMING fopen...... 158 I/O Library Functions...... 161 Copying a File...... 162 Character Input vs. Line Input...... 163 scanf...... 164 fprintf...... 167 fclose...... 168 Servicing Errors – errno.h...... 169 feof...... 170 Chapter 11: Information About Files...... 173 The stat Function...... 174 File Existence...... 176 Telling Time ­ time and ctime...... 177 Telling Time – localtime...... 179 Appendix A: Reference...... 181 Important Header Files...... 182 printf Formats...... 183 C Reserved Words...... 185 Conversion...... 187 Precedence Chart...... 189 Appendix B: Useful Library Functions...... 191 strstr...... 192 strchr, strrchr...... 194 system...... 196 strtok...... 197 strspn, strcspn...... 198 Math Functions...... 200 Character Testing Functions...... 201 exit and atexit...... 202 signal...... 203 memcpy...... 205 memset...... 206 qsort...... 207 Binary Search – bsearch...... 208

©2016 UMBC Training Centers 7 C PROGRAMMING

This Page Intentionally Left Blank

©2016 UMBC Training Centers 8 C PROGRAMMING

Chapter 1:

Getting Started

©2016 UMBC Training Centers 9 C PROGRAMMING CHAPTER 1: GETTING STARTED

What is C?

● C is a high level . ⏵ First description appeared early 1970's ⏵ Purpose was to write operating systems ⏵ was rewritten in C in the early 70's

● C is derived from the language which was used for writing .

● C is currently used in a wide variety of applications. ⏵ operating systems ⏵ networking and communications ⏵ scientific applications ⏵ graphical user interfaces ⏵ voice recognition ⏵ games

● C runs under most common operating systems.

● Language features include: ⏵ terse syntax i++, *p++

⏵ high level constructs while, for, if, switch

⏵ low level operations ­ pointers, bit operations

©2016 UMBC Training Centers 10 C PROGRAMMING CHAPTER 1: GETTING STARTED

Sample Program

● C programs are written using a text editor. The source file is then translated into an executable file by the .

● The executable file can then be launched as a command using the name of the executable. By default, the C compiler creates an executable file called a.out.

● Below is a very simple C program that demonstrates some beginning concepts.

/* This is a comment. It begins with /* and ends with */ . You will see many examples of comments throughout the lab files. */

// This is another way to a comment. // Everything from // until the end of a line // is a comment.

int main() { printf("Beginning of program\n");

printf("Every C program must have"); printf(" a function called main\n");

printf("End of program\n"); }

©2016 UMBC Training Centers 11 C PROGRAMMING CHAPTER 1: GETTING STARTED

Sample Program

● Another example of a C source file:

sample.c

1. /* 2. sample.c 3. 4. This program reads lines from standard input 5. until end­of­file, and prints and numbers lines 6. whose length is less than a specified number of 7. characters. 8. */ 9. 10. #include 11. #include 12. 13. #define MAXLINESIZE 100 14. #define LIMIT 50 15. 16. 17. int main() 18. { 19. char line[MAXLINESIZE]; 20. int i = 1, len; 21. 22. while(fgets(line, MAXLINESIZE, stdin) != NULL) 23. { 24. len = strlen(line); // Includes 25. if (len < LIMIT) 26. { 27. printf("%4d %s\n", i, line); 28. i = i + 1; 29. } 30. } 31. }

©2016 UMBC Training Centers 12 C PROGRAMMING CHAPTER 1: GETTING STARTED

Components of a C Program

● C programs contain one or more functions, exactly one of which must be named main. The source code can be in one file or many files.

● By convention, C source files are named with a .c extension.

● Every function has a header and a body.

● A function is invoked by placing a set of parentheses after the function name. The parentheses enclose zero or more function arguments.

function_name(); // Zero arg's

function_name(arg); // One arg

function_name(arg1, arg2, arg3); // Three arg's

©2016 UMBC Training Centers 13 C PROGRAMMING CHAPTER 1: GETTING STARTED

Data Types

● A dictates the number of bytes of memory to reserve and how to interpret those bytes.

● C offers four fundamental data types: int an integer

char a single character

float a decimal number (maximum 6 digits)

double a decimal number (maximum 15 digits)

● Integer types can be signed (default) or unsigned.

● Variations of the fundamental types: signed char very small integers

unsigned int bit manipulation

long int or just long

short int or just short

long double on some platforms

©2016 UMBC Training Centers 14 C PROGRAMMING CHAPTER 1: GETTING STARTED

Data Types

● Fundamental Data Types C Data Type Sample Values

int 10 35 ­45 0

char 'a' '?' '+'

'\n' '\t'

double 25.67 ­345.65765

+123.7e+25

float 32.45f 56.43F

● The operator can be used to determine the amount of storage reserved for a data type. Note that the results are always machine dependent. The values shown below are examples, but may differ depending on your particular platform.

sizeof(int) 4

sizeof(char) 1

sizeof(double) 8

sizeof(float) 4

©2016 UMBC Training Centers 15 C PROGRAMMING CHAPTER 1: GETTING STARTED

Variables

● A program with some variables defined: int main( ) { int length, width, index; char letter, dollarSign; double cost, price; float average;

... }

● The C language is case sensitive. By convention, variable and function names begin with lower case letters.

● Identifiers (names for things) in C must follow these rules: ⏵ Case sensitive ⏵ Can contain letters, digits, and underscores ⏵ Cannot begin with a digit ⏵ Use of leading underscore discouraged

● Variables must be declared before they are used.

©2016 UMBC Training Centers 16 C PROGRAMMING CHAPTER 1: GETTING STARTED

Printing and Initializing Variables

● Examples of initialization: int main( ) { int len = 5, width = 10, index = 0; char letter = 'A', dollarSign = '$'; double cost = 10.95, price; float average = 0.0;

... }

● You do not have to initialize, but the following can lead to problems. int x; // Initial value = ???

x = x + 1;

print.c

1. /* print.c */ 2. 3. #include 4. 5. main( ) 6. { 7. int len = 5, wid = 10, tot; 8. char letter = 'A'; 9. float average = 0.0; 10. 11. tot = len + wid; 12. printf("%+%d is %d\n", len, wid, tot); 13. printf("average = %f\n", average); 14. printf("letter = %c\n", letter); 15. }

©2016 UMBC Training Centers 17 C PROGRAMMING CHAPTER 1: GETTING STARTED

Printing and Initializing Variables

● A variable can be initialized as part of its declaration.

● A non­initialized local variable has an unknown value. ⏵ A local variable is one declared inside of a function. ⏵ Later we will also talk about global variables.

● Use the printf function to display the values of variables. This function uses a control string and a list of expressions. printf ("control string", comma­separated expressions);

● The control string is printed literally except for the % symbol and certain characters which follow. The % and certain following characters represent a format under which an expression will be printed. %d int

%c char

%f double, float

● A comma separates the control string from the list of expressions. The list itself is comma separated.

©2016 UMBC Training Centers 18 C PROGRAMMING CHAPTER 1: GETTING STARTED

Arrays

● An array is an ordered collection of data items, all of which have the same name and data type.

● An array element is referenced by the array name followed by some integer value in square brackets.

● For an array with N elements, legal subscripts would range from 0 to N ­ 1. C does not perform subscript checking.

● An array name without a subscript refers to the place in memory where the array is stored. This location is referred to as the base address of the array. We will explore this concept in depth when we study pointers.

©2016 UMBC Training Centers 19 C PROGRAMMING CHAPTER 1: GETTING STARTED

Arrays

● Here are a few examples of declaring arrays. int numbers[50]; // 50 int's

char word[20]; // 20 char's

double prices[100]; // 100 double's

● You can use the sizeof operator to determine the amount of memory (machine dependent) occupied by an array. sizeof(numbers) // 50 * sizeof(int)

sizeof(word) // 20 * sizeof(char)

sizeof(prices) // 100 * sizeof(double)

● A declaration can include arrays and regular variables. int x, y, z, values[50], r;

● Array elements are referenced by using a subscript within square brackets. values[30] = 0;

x = values[20] + y;

©2016 UMBC Training Centers 20 C PROGRAMMING CHAPTER 1: GETTING STARTED

Compiling and Executing a C Program

example.c

1. /* example.c */ 2. 3. #include 4. 5. int main() 6. { 7. printf("This is my first C program\n"); 8. }

1. Follow the instructions given by your instructor to create a source file with your text editor.

2. Compile the source file to produce an executable file.

3. Run and test your program.

©2016 UMBC Training Centers 21 C PROGRAMMING CHAPTER 1: GETTING STARTED

Exercises

1. The following program contains multiple errors. Find each error and re­write the program so that it compiles and executes without any errors. Int Main() { integer a = 5; printf(%f, a)

2. Write a program, which contains ONE printf statement such that your first and last names are printed on separate lines. For example: michael saltzman

3. Write a printf statement, which displays exactly what you see below the code. int main() { int x, y;

x = 3; y = 4; printf( YOU FINISH THIS STATEMENT... ); }

Output:

(x,y) = (3,4)

©2016 UMBC Training Centers 22 C PROGRAMMING CHAPTER 1: GETTING STARTED

Exercises

4. Finish the program below: int main() { int a = 5, b = 10; double x = 25.5, y = 20;

... }

⏵ Write a printf statement which prints the sum of the two int's. ⏵ Write a printf statement which prints the product of the two int's. ⏵ Do the same for the two double's.

5. 5. Write a program that displays the following: H H E E E L L O O O H H E L L O O H H H E E E L L O O H H E L L O O H H E E E L L L L L L O O O

©2016 UMBC Training Centers 23 C PROGRAMMING CHAPTER 1: GETTING STARTED

This Page Intentionally Left Blank

©2016 UMBC Training Centers 24 C PROGRAMMING

Chapter 2:

Functions and Operators

©2016 UMBC Training Centers 25 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Functions

● Every C function has the following parts: ⏵ return type of the function int ⏵ name of the function sum ⏵ parenthesized list of parameters (int a, int b) ⏵ an opening curly brace { ⏵ the function body consisting of: • variable declarations int c; • executable statements c = a + b; • return statement return(c); ⏵ a closing curly brace }

● Examples: int sum(int a, int b) { int c;

c = a + b; return(c); }

double average(int hits, int at_bats) { double bat_avg;

bat_avg = hits; bat_avg = bat_avg/at_bats; return(bat_avg); }

©2016 UMBC Training Centers 26 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Functions sum.c

1. /* sum.c */ 2. 3. #include 4. 5. main() 6. { 7. int answer; 8. int number1, number2; 9. 10. number1 = 10; 11. number2 = 20; 12. 13. printf("Starting\n"); 14. answer = sum(number1, number2); 15. printf("Sum is %d\n",answer); 16. printf("Ending\n"); 17. } 18. 19. int sum(int a, int b) 20. { 21. int c; 22. 23. c = a + b; 24. return(c); 25. }

● Output: Starting Sum is 30 Ending

©2016 UMBC Training Centers 27 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Elementary Operators

Arithmetic Meaning Example + addition a = b + c ­ subtraction a = b ­ c * multiplication a = b * c / division a = b / c % modulus a = b % c

Relational Meaning Example > greater than (gt) a > b >= gt or equal to a >= b < less than (lt) a < b <= lt or equal to a <= b != not equal to a != b == equal to a == b

Logical Meaning Example ! logical not ! a > b && logical and a > b && c < d || logical or a > b || c < d

Bitwise Meaning Example >> right shift a = a >> 3 << left shift b = b << 3 & bitwise and a = a & b | bitwise or a = a | b ~ complement a = ~ b ^ bitwise xor a = a ^ b

©2016 UMBC Training Centers 28 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Assignment Operators

● Certain operations are common to all programming languages. x = x + 5; /* add 5 to x */ x = x * 10; /* multiply x by 10 */ x = x / 5; /* divide x by 5 */

● In C, these can be written as: x += 5; /* add 5 to x */ x *= 10; /* muliply x by 10 */ x /= 5; /* divide x by 5 */

● Any binary operator can be written in the above form, for example, the left shift operator. x <<= 3; /* left shift 3 bits */

● The collection of these binary operators is referred to as the arithmetic assignment operators.

©2016 UMBC Training Centers 29 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Increment and Decrement Operators

● A most common expression for a compiler is: x = x + 1 /* add one to x */

● In C this can be accomplished with: x++; /* post increment */

++x; /* pre increment */

● The two expressions are equivalent only when they are statements themselves and not part of a larger expression. Therefore, the following are not equivalent. r = x++; /* use 'x', then increment */ r = ++x; /* increment 'x' first */

● Correspondingly, post and pre decrement operators also exist. r = x­­; /* use x, then decrement */ r = ­­x; /* decrement x first */

©2016 UMBC Training Centers 30 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Increment and Decrement Example

● Given: int x = 2; int y = 3;

● Then: x y ­­­ ­­­ x = y++; 3 4

x = ++y; 5 5

x = y­­; 5 4

x = ­­y; 3 3

©2016 UMBC Training Centers 31 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Number of Operands

● Most operators are binary (two operands) x + y add a * b multiply a / b divide a << 3 left shift

● A few are unary (one operand): ­b unary minus !x logical not i++ increment

©2016 UMBC Training Centers 32 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Conditional Operator

● The conditional operator is the only ternary (requires three operands) operator in C. ⏵ It consists of three operands separated by the ? and the : condition ? expr1 : expr2

⏵ The value of this expression is either expr1 or expr2, depending upon whether the test condition is true or false, respectively.

● Examples: // x GETS THE LARGER OF a OR b

x = a > b ? a : b;

// PRINT THE SMALLER OF p OR q

printf("%d\n", p < q ? p : q);

// PRINT EITHER one or many

if (n > 0) { printf( n == 1 ? "one" : "many"); }

©2016 UMBC Training Centers 33 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Exercises

1. Find the error in each function definition below: (a) int main(); { printf("a simple function\n"); }

(b) int mult(int a, b) { return( a * b ); }

(c) int main() { int a = 5, b = 10; c = a + b; }

2. What gets printed in the code segments below? (a) int x = 5, y = 10, r = 7, z = 12;

x = x + y++; printf("%d %d\n", x, y);

r += ++z; printf("%d %d\n", r, z);

(b) int a = 5, b = ­5;

printf("%d", a + b ? a + b : a ­ b);

©2016 UMBC Training Centers 34 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Exercises

3. Write a program that includes the following statements in its main function: int a = 17, b = 4, c;

c = a + b; printf("%d + %d = %d\n", a, b, c);

Run the program and interpret the results. Then add similar statements for the / and % operators so that the results of all three calculations appear in the output.

4. Write and test a function that computes the sum of the squares of its two argument. Your test code might look this: int a = 5, b = 6, c;

c = sum_of_squares(a, b); // c = 61

©2016 UMBC Training Centers 35 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Exercises

5. Write and test a function that determines if the three sides of a triangle form a right triangle. Your function should: ⏵ take advantage of the function written in the previous exercise. ⏵ accept three integer arguments, where the first two represent the shorter sides of the triangle and the third argument is the longest side. ⏵ return the value 1 (true) if the three sides form a right triangle and 0 (false) otherwise.

Your test code might look like this:

int side1 = 3, side2 = 4, side3 = 5;

printf ("%d, %d, and %d are ", side1, side2, side3);

if ( is_right(side1, side2, hypotenuse) == 0 ) { printf("NOT "); }

printf("the sides of a right triangle\n");

// 3, 4, and 5 are the sides of a right traingle

©2016 UMBC Training Centers 36 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

Exercises

6. Write a program to compute the amount of the monthly payment on a loan based on the formula below. M = P * ( J / ( 1 ­ (( 1 + J) ** ­ N)))

where

M = Monthly payment P = Loan amount I = Interest rate J = I / (12 x 100) N = Number of months over which loan is amortized

Note that in the formula, ** represents exponentiation, in other words, (1 + J) ** N means (1 + J) raised to the power of N. C does not have this operator, so you must use the pow function. For example, to raise 2 to the power of 3, you would write pow(2, 3).

To use the pow function, you must add the following at the beginning of your program: #include

Under Linux, you must also compile with the ­lm option at the end of the command line. For example: gcc myprog.c ­lm

Test your program by computing the monthly payment for a $200,000 mortgage at 7.5% over 30 years. • The result should be 1398.43.

©2016 UMBC Training Centers 37 C PROGRAMMING CHAPTER 2: FUNCTIONS AND OPERATORS

This Page Intentionally Left Blank

©2016 UMBC Training Centers 38 C PROGRAMMING

Chapter 3:

Control Flow Constructs

©2016 UMBC Training Centers 39 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Conditionals

● C has a rich set of control flow constructs, most of which include a test condition that must be evaluated and true or false.

● The general rule in C is the value zero is considered to be false, and any non­zero value is considered to be true.

● Given: int x = 10, y = 20, p = 10;

The following expressions have the indicated values:

EXPRESSION VALUE TRUTH VALUE

x < y 1 TRUE p == y 0 FALSE y > x && x == p 1 TRUE x 10 TRUE 1 1 TRUE ­23 ­23 TRUE 0 0 FALSE

©2016 UMBC Training Centers 40 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

if

● The if statement allows you to execute a group (one or more) of statements depending on the truth value of a logical expression.

● An expression consists of a combination of operators and operands yielding a value of zero or non­zero value.

● The general form of an if statement is: if (expression) { body; }

● There are other variations of the if statement.

● The if­else construct allows an else part to be executed when the test expression is false. if (expression) { true_body; } else { false_body; }

● Note that when there is a single statement within the if or the else, the curly braces can be omitted.

©2016 UMBC Training Centers 41 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

if

● Example 1 if (a == b) { printf ("a HAS SAME VALUE AS b\n"); }

● Example 2 if (a < b) { printf("a AND b ARE DIFFERENT\n"); printf("a = %d\n", a); printf("b = %d\n", b); }

● Example 3 if (a > b) { printf ("a is greater than b\n"); } else { printf ("a is less than or equal to b\n"); }

● Example 4 if (a > b) { printf ("a is greater than b\n"); printf ("a is %d\n", a); } else { printf ("a is less than or equal to b\n"); printf ("a is %d\nb is %d\n", a, b); }

©2016 UMBC Training Centers 42 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

if­else­if

● The if­else­if construct can be used to perform a multi­way branch.

● Any number of if's are allowed. ⏵ Conditions are tested in order. ⏵ If the tested condition is true, all statements in the body are executed, and control passes to the first statement after the entire construct. ⏵ If none of the test conditions are true, the else body (optional) is executed.

©2016 UMBC Training Centers 43 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

if­else­if

if.c

1. #include 2. #include 3. #include 4. 5. int get_menu_selection(void); 6. void get_dir_listing(void); 7. void copy_files(void); 8. void quit_function(void); 9. 10. int main () 11. { 12. int x; 13. 14. while(1) { 15. x = get_menu_selection(); 16. 17. if ( x == 0 || x == 'd') { 18. printf("...getting dir listing...\n"); 19. get_dir_listing(); 20. } 21. else if ( x == 1 || x == 'c') { 22. printf("...copying files...\n"); 23. copy_files(); 24. } 25. else if ( x == 2 || x == 'q') { 26. printf("...quitting...\n"); 27. quit_function(); 28. } 29. else { 30. printf("Illegal choice\n"); 31. } 32. } 33. } 34.

©2016 UMBC Training Centers 44 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

switch

if.c (continued)

35. int get_menu_selection() 36. { 37. char c[10]; 38. int x; 39. 40. printf("Enter menu selection:\n"); 41. printf("\t0 or d for a directory listing\n"); 42. printf("\t1 or c to copy files\n"); 43. printf("\t2 or q to quit\n"); 44. 45. fgets(c, 10, stdin); 46. 47. if (c[0] <= '9' && c[0] >= '0') { 48. x = atoi(c); 49. } else { 50. x = c[0]; 51. } 52. 53. return x; 54. } 55. 56. void get_dir_listing() 57. { 58. printf("Inside get_dir_listing\n"); 59. } 60. 61. void copy_files() 62. { 63. printf("Inside copy_files\n"); 64. } 65. 66. void quit_function() 67. { 68. exit (0); 69. }

©2016 UMBC Training Centers 45 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Loops

● There are three iterative constructs in C: ⏵ while ⏵ for ⏵ do while

● In general, curly braces are required when the body contains more than one statement and optional when there is only a single statement.

©2016 UMBC Training Centers 46 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

while

● The while has two parts: the header (which contains the test condition) and the body. while (condition) { body; }

● A simple loop to add integers 1 ­ 10: int i = 1; int sum = 0;

while (i <= 10 ) { sum = sum + i; i = i + 1; }

● Be careful of loops such as the following. The increment in the loop occurs even when the test is false. int i = 0;

while (i++ < 5 ) { body; }

©2016 UMBC Training Centers 47 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

for

● The for loop has two parts: the header (three pieces) and the body. for (initialization; condition; update) { body; }

● Initializing an array int i, x[10];

for (i = 0; i < 10; i++) { x[i] = 0; }

● Accumulating a sum int i, sum = 0;

for (i = 0; i < 10; i++) { sum = sum + i; }

● Any of the expressions in a for loop can be omitted, but the semi­colons must be present. int i = 0;

for ( ; i < 10; ) { x[i] = 0; i++; }

⏵ If the test condition of a for loop is omitted, the test is evaluated as true. ©2016 UMBC Training Centers 48 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

do­while

● Both while and for are looping constructs with tests at the beginning of the loop.

● The do while executes a test at the end of the loop. do { body; } while(condition);

● Assigning array values int i = 0; char line[100], text[100];

do { line[i] = text[i]; } while(text[i++] != ' ');

● Another way to write the same loop as above int i = ­1; char line[100], text[100];

do { i++; line[i] = text[i]; } while(text[i] != ' ');

©2016 UMBC Training Centers 49 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Endless Loops

● Although endless loops are sometimes intentional, they can also be the result of a programmer error.

● Programmer error i = 0;

while (i < 10 ) { sum = sum + i; printf ("sum is %d\n", sum); }

/* forgot to increment 'i' in the loop */

● An intentional endless for loop for( ; ; ) { body; }

● An intentional endless while loop while(1) { body; }

©2016 UMBC Training Centers 50 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

break and continue

● Loops are often written to search a file or an array. These loops terminate when: ⏵ The sought value is found (premature exit) ⏵ Did not find sought value (exhaustion)

● The break statement allows: ⏵ Early termination in any looping construct ⏵ Early exit from a switch construct (next page)

● The continue statement transfers control to the bottom of a loop.

©2016 UMBC Training Centers 51 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

break and continue

● break int x[100], i = 0;

/* Fill the array somehow. */ /* Now 'lookup' a value. */

while( i < 100 ) { if (x[i] == specific_value) { break; }

i++; }

if (i == 100) { printf("Did NOT find\n"); } else { printf("Found\n"); }

● continue int x[100], i, sum = 0;

for (i = 0; i < 100; i++) { if (x[i] < 0) { continue; }

if (x[i] == 0) { break; }

sum += x[i]; }

©2016 UMBC Training Centers 52 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

switch

● The switch is another kind of multi­way branch. It is often used instead of a series of if­else­if's.

● Depending upon the value of the switch expression, one of several paths may be taken.

● break is necessary to exit each case.

● The default case is executed when there are no matching cases.

©2016 UMBC Training Centers 53 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

switch switch.c

1. #include 2. #include 3. #include 4. 5. int get_menu_selection(void); 6. void get_dir_listing(void); 7. void copy_files(void); 8. void quit_function(void); 9. 10. int main() 11. { 12. int x; 13. 14. while(1) { 15. x = get_menu_selection(); 16. 17. switch(x) { 18. case 0: 19. case 'd': 20. printf("...getting dir listing...\n"); 21. get_dir_listing(); 22. break; 23. 24. case 1: 25. case 'c': 26. printf("...copying files...\n"); 27. copy_files(); 28. break; 29. 30. case 2: 31. case 'q': 32. printf("...quitting...\n"); 33. quit_function(); 34. 35. default: 36. printf("Illegal choice\n"); 37. } 38. } 39. } 40. 41. // Other functions same as in if.c

©2016 UMBC Training Centers 54 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Exercises

1. What gets printed in the code segment below? int a = 5, b = 0, c = 5;

if ( a = b ) printf("a equals b\n"); if ( c == a ) printf("c equals a\n");

2. Which of the following are correct initializations of the array numbers? int numbers[10], i; (a) for ( i = 1; i <= 10; i++) numbers[i] = 0;

(b) i = 1; while( i < 10 ) { numbers[i] = 0; i++; }

(c) i = ­1; do { i++; numbers[i] = 0; } while ( i < 10);

(d) i = 0; while(i < 10) numbers[i++] = 0;

(e) for (i = 0; i < 10; i++) numbers[i] = 0;

©2016 UMBC Training Centers 55 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Exercises

3. Which of the following will compile? int a, b, c;

(a) if ( a > b ) c = a; b = c;

(b) if ( a > b ) c = a; b = c; else c = b;

4. Write a program that sums the integers from 1 to 100 inclusive. Use a for loop.

5. Repeat problem (4) but this time use a while loop.

6. Repeat problem (4) but this time just sum the integers that are divisible by 5.

7. Use nested for loops to produce the following output: 1 2 1 3 2 1 4 3 2 1 5 4 3 2 1 6 5 4 3 2 1 7 6 5 4 3 2 1

©2016 UMBC Training Centers 56 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Exercises

8. Use nested while loops to produce the following output:

1 2 3 4 5 6 7 1 2 3 4 5 6 1 2 3 4 5 1 2 3 4 1 2 3 1 2 1

9. Print a table showing the even integers between 20 and 60 in the first column, their squares in the second column, and their cubes in the third column. 10. Add statements inside the for loop shown below such that the desired output is produced. int i;

for (i = ­4; i <= 4; i++) { // Add statements here }

Ouput:

­4 is negative and even ­3 is negative and odd ­2 is negative and even ­1 is negative and odd 0 is even 1 is positive and odd 2 is positive and even 3 is positive and odd 4 is positive and even

©2016 UMBC Training Centers 57 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Exercises

11. Write a program that uses a while loop to compute 10 factorial. 12. Write a program that produces those sets of consecutive integers totaling exactly 10,000. 13. Write a program that prints out the numbers from 1 to 50, but for multiples of 3, print "Fizz" instead of the number, and for multiples of 5, print "Buzz" instead of the number. For numbers which are multiples of both 3 and 5, print "FizzBuzz". ⏵ This problem is a well­known job interview filter question, often eliminating over 99.5% of candidates.

14. According to the United States constitution, a person is eligible to be a US Senator if they are at least 30 years old and have been a citizen for at least 9 years. They are eligible to be a US Representative if they are at least 25 years old and have been a US citizen for 7 years. To be president, a person must be at least 35 years old and be born as a US citizen (i.e., a citizen their entire life). Write and test a function that takes a person's age and years of citizenship, and then prints their eligibility for each of these positions. Examples: ⏵ The function is called with age 57 and 14 years of citizenship: Not eligible for Presidency Eligible for Senate Eligible for House ⏵ The function is called with age 69 and 69 years of citizenship: Eligible for Presidency Eligible for Senate Eligible for House

©2016 UMBC Training Centers 58 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

Exercises

15. Body Mass Index (BMI) is calculated by taking the weight in kilograms (1 kg = 2.20462 lb) and dividing it by the square of the height in meters (1 in = 0.0254 m). Write and test a function that that takes a weight in pounds and a height in inches, and then prints the BMI and category: ⏵ Underweight = less than 18.5 ⏵ Normal weight = 18.5 – 24.9 ⏵ Overweight = 25 – 29.9 ⏵ Obese = 30 or greater

Examples:

⏵ The function is called with weight 146 and height 70 : BMI is 20.95 Normal

⏵ The function is called with weight 108 and height 65 : BMI is 17.97 Underweight

⏵ The function is called with weight 57 and height 14 : BMI is 20.95 Normal

©2016 UMBC Training Centers 59 C PROGRAMMING CHAPTER 3: CONTROL FLOW CONSTRUCTS

This Page Intentionally Left Blank

©2016 UMBC Training Centers 60 C PROGRAMMING

Chapter 4:

The

©2016 UMBC Training Centers 61 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

#define

● The C compiler proceeds in three phases ⏵ Preprocessor produces a .i file ⏵ Compiler produces a .o file (.obj) ⏵ Loader produces an executable ● The C preprocessor reads your source file and: ⏵ copies it to a .i file; ⏵ strips comments; and ⏵ makes substitutions for lines beginning with #. ● The preprocessor, #define , allows you to create symbolic names for expressions. For example: #define MAXIMUM 100

directs the preprocessor to replace all occurrences of MAXIMUM (in your source file) with 100.

● The #define mechanism is most often used in two cases. ⏵ array bounds ⏵ readability

©2016 UMBC Training Centers 62 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

#define

● For array bounds #define MAXSIZE 100

char line[MAXSIZE];

● For readability #define NOT_ALL_DIGITS 1

if(check(line) == NOT_ALL_DIGITS) printf("bad input\n");

● Tips ⏵ Use UPPER CASE convention for #define symbols. ⏵ Substitutions are not made inside strings. ⏵ Preprocessor lines do not end in a semi­colon.

©2016 UMBC Training Centers 63 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

Preprocessor Macros

● Substitutions with #define can also have arguments. These are often called macros.

● Suppose there are many places in your code where you need to perform the same task (e.g. square a value). There are many different solutions: ⏵ in line ⏵ ⏵ function

● Preprocessor substitutes in the macro definition, then when the macro is invoked, the expression in the invoked macro replaces in accordance with the dummy argument in the macro definition.

● Conditional expressions make good candidates for macros. #define ISDIGIT(X) ((X)>='0' && (X)<='9') ? 1: 0

©2016 UMBC Training Centers 64 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

Preprocessor Macros

● Create and use the SQUARE macro. square.c

1. #include 2. 3. #define SQUARE(VAL) ((VAL) * (VAL)) 4. 5. main() 6. { 7. int r; 8. int i = 5; 9. int k = 4; 10. int j = 2; 11. 12. r = SQUARE(k); 13. printf("%d\n", SQUARE(i + j)); /* 49 */ 14. printf("%d\n", SQUARE(i + j) + k); /* 53 */ 1. }

● The preprocessor will substitute as shown below: r = ((k) * (k)); printf("%d\n", ((i + j) * (i + j)) ); printf("%d\n", ((i + j) * (i + j)) + k);

● Know when to parenthesize. printf("%d\n", i + j * i + j + k); /* 21 */

©2016 UMBC Training Centers 65 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

#include

● The preprocessor looks for lines in your source code which begin with a #.

● A #include line is a substitution directive. #include ⏵ Look for filename in a well known directory. #include "filename.h" #include "/home/student/filename.h" ⏵ Look for filename in the specified relative path.

● In either case, the file is copied as if it were a part of your program (as if you had "included" it). ⏵ Saves you lots of typing ⏵ Insures consistency

● Included files are called header files. File names for header files conventionally end in .h.

©2016 UMBC Training Centers 66 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

Conditional Compilation

● Do something as a function of a symbol being defined.

conditional.c

1. #include 2. 3. main() 4. { 5. #ifdef DEBUG 6. printf("Debugging\n"); 7. #elif PRINT_ARRAY 8. printf("Printing arrays\n"); 9. #endif 10. }

define.c

1. #include 2. 3. #define SUM 12 4. 5. main() 6. { 7. int x; 8. #ifdef SUM 9. x = 20; 10. printf("SUM is %d. x is %d.\n", SUM, x); 11. #else 12. x = 100; 13. printf("SUM doesn't exist. x is %d.\n", x); 14. #endif 15. }

©2016 UMBC Training Centers 67 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

Conditional Compilation

● A definition can also be made known to your source code through an option on the command line.

/* NAME is defined */ $ cc ­DDEBUG sourcefile.c

/* NAME is not defined */ $ cc sourcefile.c

● #ifdef can also be written as: #if defined(DEBUG)

● There are many different operating systems and many different machine architectures. specific code will not be portable. You can conditionally compile your code to guard against this.

©2016 UMBC Training Centers 68 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

#ifndef

● Insulate against the possibility of a multiply defined symbol occurring through the inclusion of more than one file. #ifndef ANSI_STANDARD_C #define ANSI_STANDARD_C

/* could be more statements here */

#endif

● Guard against the possibility of a multiply defined header file. #ifndef HEADERFILE_H #define HEADERFILE_H

/* header file is defined */

#endif

©2016 UMBC Training Centers 69 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

#ifndef

● Only one definition is allowed for the same name in the same source file.

● The #undef directive removes a name from the #define list. #undef NAME

● It is common for C source files to contain several include files each of which may contain #define lines. Therefore, using #undef is not a simple issue.

● It is also common for many include files to have the same #define directive. #define ANSI_STANDARD_C

● Inclusion of more than one of these files results in ANSI_STANDARD_C being multiply defined. You can avoid this problem by using the #ifndef directive.

©2016 UMBC Training Centers 70 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

Exercises

1. What gets printed in the programs below? (a) #define HIGH 100 #define LOW 20 #define MID (HIGH + LOW) / 2

int main() { int x = MID;

printf("%d", x); }

(b) #define MIN(A,B) (A) < (B) ? (A) : (B)

int main() { int a = 3, b = ­5, c;

printf("%d\n", MIN(3, 5)); c = MIN( a * b, b * b); printf("%d\n", c); }

(c) #define XTIMES2 x + x

int main() { int a, b, x = 5;

a = XTIMES2; b = XTIMES2 * 3; printf("%d %d\n", a,b); }

(d) #define PRINT(X,Y) printf("%d %d\n", X,(X* Y))

int main() { int a = 5, b = 6;

PRINT(a,b); PRINT(b, a + b); }

©2016 UMBC Training Centers 71 C PROGRAMMING CHAPTER 4: THE C PREPROCESSOR

Exercises

(e) int main() { int a; #ifdef MIKE a = 100; printf("MIKE defined: a = %d\n", a); #else a = 50; printf("MIKE not defined: a = %d\n", a); #endif

}

©2016 UMBC Training Centers 72 C PROGRAMMING

Chapter 5:

Simple I/O

©2016 UMBC Training Centers 73 C PROGRAMMING CHAPTER 5: SIMPLE I/O

Character I/O

● A program segment with getchar() /* GET A CHARACTER FROM KEYBOARD */ int c;

c = getchar();

● A program segment with putchar() int c;

c = 'A'; putchar(c); /* OUTPUT AN 'A' */ putchar('\n'); /* OUTPUT THE NEWLINE */ putchar('?'); /* OUTPUT A '?' MARK */ putchar('\n'); /* ANOTHER NEWLINE */

● An entire program using getchar() and putchar() copy.c

1. /* 2. Copy standard input to standard output 3. */ 4. 5. #include 6. 7. main() 8. { 9. int c; 10. 11. c = getchar(); /* GET A CHAR */ 12. while( c != ­1) /* WHILE NOT EOF */ 13. { 14. putchar(c); /* DISPLAY IT */ 15. c = getchar(); /* GET ANOTHER */ 16. } 17. }

©2016 UMBC Training Centers 74 C PROGRAMMING CHAPTER 5: SIMPLE I/O

Character I/O

● Two functions allow character terminal I/O. ⏵ getchar() • Get next character from the standard input file. ⏵ putchar(c) • Output a character on the standard output file.

● getchar() normally returns the next character. However, the integer value ­1 is returned at end­of­file.

● Therefore, the returned value should be kept in a variable of type int.

©2016 UMBC Training Centers 75 C PROGRAMMING CHAPTER 5: SIMPLE I/O

End of File

● Define EOF to make programs easier to read. #define EOF (­1)

● The header file stdio.h contains many useful constants, one of which is the definition for EOF. By including stdio.h, you can refer to EOF.

● Assignments in C can occur within expressions leading to compact code.

● Including the header file stdio.h where EOF is defined: #include

main() { int c;

c = getchar(); // "priming" read while (c != EOF) { putchar(c); c = getchar(); } }

©2016 UMBC Training Centers 76 C PROGRAMMING CHAPTER 5: SIMPLE I/O

End of File

● A different form of the while test: copy2.c

1. #include 2. 3. main() 4. { 5. int c; 6. while(( c = getchar()) != EOF) 7. putchar(c); 8. }

©2016 UMBC Training Centers 77 C PROGRAMMING CHAPTER 5: SIMPLE I/O

Simple I/O Examples

chars.c

1. /* Count characters in standard input */ 2. 3. #include 4. 5. main() 6. { 7. int count = 0; 8. 9. while( getchar() != EOF) 10. count++; 11. 12. printf("%d characters \n", count); 13. }

lines.c

1. /* Count lines in standard input */ 2. 3. #include 4. 5. main() 6. { 7. int lines = 0; 8. int c; 9. 10. while(( c = getchar()) != EOF) 11. if( c == '\n') 12. lines++; 13. 14. printf("%d lines\n", lines); 15. }

©2016 UMBC Training Centers 78 C PROGRAMMING CHAPTER 5: SIMPLE I/O

Simple I/O Examples

strip.c

1. /* Strip non­digit characters */ 2. 3. #include 4. 5. main() 6. { 7. int c; 8. 9. while(( c = getchar()) != EOF) 10. if( c >= '0' && c <= '9') 11. putchar(c); 12. }

©2016 UMBC Training Centers 79 C PROGRAMMING CHAPTER 5: SIMPLE I/O

Simple I/O Redirection

● End of file is signaled from the keyboard by typing Ctrl­D (Unix) or Ctrl­Z (DOS / Windows).

● Command line argument interfaces offer the following: ⏵ Use the special symbol < on the command line take the input from the file named after the <. ⏵ Use the special symbol > to send the standard output to a file.

● Suppose data contains five lines and 83 characters. ⏵ Redirection of standard input examples $ lines < data # Input from data 5 lines

$ chars < data 83 characters

⏵ Redirection of standard output examples $ chars < data > outputfile

$ cat outputfile # To prove it worked 83 characters

$ chars > output hello there # Type end­of­file char.

©2016 UMBC Training Centers 80 C PROGRAMMING CHAPTER 5: SIMPLE I/O

I/O with Character Arrays

● Reading a single line char line[100]; int i = 0, c;

while (( c = getchar()) != '\n') line[i++ ] = c;

line[i] = '\0'; // Insert null character

0 1 2 3 4 ...... 99 M i k e \0

● Printing the line int k;

for (k = 0; k < i; k++) putchar(line[k]);

putchar('\n');

● Some functions gets(line); /* READS A LINE */ puts(line); /* PRINT A LINE */ printf("%s\n", line); /* PRINT A LINE */

©2016 UMBC Training Centers 81 C PROGRAMMING CHAPTER 5: SIMPLE I/O

I/O with Character Arrays

● A collection of characters can be organized into a character array. This is useful for reading a user's response such as a filename, or any string in general.

● A string is kept in memory as a character array. It is typically terminated with the null character as shown below.

● String constants printf("this\nis\nit\n");

t h i s \n i s \n i t \n \0

©2016 UMBC Training Centers 82 C PROGRAMMING CHAPTER 5: SIMPLE I/O

Exercises

1. Write a program to display just the alphabetic characters in the input file.

2. Write a program to display a file such that there is a blank line between each text line. (Double space the file).

3. Write a program to display only those lines of a file whose lengths are less than twenty.

4. Write a program to display only those lines of a file whose first and last characters are the same.

©2016 UMBC Training Centers 83 C PROGRAMMING CHAPTER 5: SIMPLE I/O

This Page Intentionally Left Blank

©2016 UMBC Training Centers 84 C PROGRAMMING

Chapter 6:

More on Functions

©2016 UMBC Training Centers 85 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Introduction

● As program size increases, program complexity grows beyond what a single programmer can understand.

● To unburden the programmer, software solutions are generally divided into smaller more manageable pieces called functions.

● Functions offer many advantages including: ⏵ Incremental compilation ⏵ Reusability

● Some functions compute a value. int sum(int first, int second) { int c;

c = first + second; return(c); }

● When a function does compute a value, the function invocation may be used like other values: ⏵ In a computation ⏵ In a variable assignment ⏵ In a test

©2016 UMBC Training Centers 86 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Function Declarations

● Consider the definition for the function sum.

● When sum is invoked in a program, you should provide a declaration for it, which is visible to the invoking function.

declaration.c

1. #include 2. 3. int sum(); /* declaration */ 4. 5. int main() 6. { 7. int a, b, c; 8. 9. printf("Invoking sum\n"); 10. a = sum(b, c); /* invocation */ 11. 12. printf("%d is sum of %d and %d\n", a, b, c); 13. } 14. 15. int sum(int first, int second) /* definition */ 16. { 17. int c; 18. 19. c = first + second; 20. return(c); 21. }

● In ANSI C, a function prototype can be used instead of a function declaration.

©2016 UMBC Training Centers 87 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Returning a Value or Not

● Some functions do not return a value. ⏵ A function could the values in an array. int numbers[MAX]; sort(numbers,MAX); ⏵ A function could copy one string to another. char text[MAXSIZE], line[MAXSIZE]; strcpy(line, text);

● Since there are two distinct uses of functions in C, you must describe to the compiler: ⏵ Whether or not the function returns a value ⏵ What is the type of the value that is returned

● You must report the above information twice. ⏵ In the function definition ­ the file where the source code for the function is located. ⏵ In a function declaration (K & R C)

©2016 UMBC Training Centers 88 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Function Prototypes

● Before ANSI C, C compilers did not do type checking between arguments and parameters.

● ANSI C provides a way (the function prototype), for the compiler to perform type checking.

● The prototype for the sum function would be either: int sum(int, int); int sum(int addend1, int addend2);

● The prototype specifies the types of the parameters in addition to the return type of the function. ⏵ The prototype also allows you to specify names so that programmers are provided with a documentation aid.

● Prototypes should appear before the function is called. ⏵ Before main ⏵ In header files

©2016 UMBC Training Centers 89 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Function Prototypes

prototype.c

1. /* prototype for sum */ 2. int sum(int addend1, int addend2); 3. 4. /* Definition of main */ 5. int main() 6. { 7. int a, b = 10, c = 15; 8. 9. printf("Invoking sum\n"); 10. a = sum(b, c); 11. 12. printf("%d is sum of %d and %d\n", a, b, c); 13. } 14. 15. /* Definition of sum */ 16. int sum(int first, int second) 17. { 18. int c; 19. 20. c = first + second; 21. return(c); 22. }

● Notice that the function prototype and the opening line of the function definition (the function header) are very close in format.

©2016 UMBC Training Centers 90 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Arguments and Parameters

● A function needs to know on which data to do its work. ⏵ For example, the sum function needs to know what to sum. Likewise, an input function needs to know where to store the data that it is getting.

● Those names that are sent to the function are called function arguments.

● A function needs to have a corresponding parameter for each argument sent to it.

● The compiler creates a relationship between arguments and parameters.

● Each non­array argument has its value copied to its corresponding parameter. ⏵ Non­array arguments cannot be modified by a function call (with what we know thus far!)

● Each array argument has its address copied to its corresponding parameter. ⏵ Array arguments can be modified by a function call.

● In main, before the sum function is called, the variables have the following values: a unknown b 10 c 15

©2016 UMBC Training Centers 91 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Arguments and Parameters

● Once the function has been called, the parameters, first and second are created and they contain the values as shown here. first 10 second 15

● Even if these parameters are modified within the sum function, this would have no effect on their corresponding arguments, b and c. int sum(int first, int second) { int c;

c = first + second; first = 99; // no effect on // 'b' in main() return(c); }

● The variable c is local to the function. In this example, it provides a place to store the sum of first and second, before that sum is returned to the calling function, main.

● The return statement sends the value being returned, c, back to the calling function, main. It is as if this value replaces the calling expression sum(b, c) in the statement: a = sum(b, c);

©2016 UMBC Training Centers 92 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Organization of C Source Files

● Each C source file should have the following general organization: ⏵ #include's ⏵ #define's ⏵ Function prototypes ⏵ main function ⏵ Other functions

©2016 UMBC Training Centers 93 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Extended Example

● We now present an extended example demonstrating function definitions, prototypes, and invocations.

● Problem: Write a program prompting the user to enter a number. If a valid number is entered, it is placed into an array of integers. Repeat the process until the user enters the word quit. The program prints the average of the numbers and then terminates.

● Since there are many distinct pieces to this program, the work is divided into functions.

● A "pseucocode" translation of the problem is: loop forever

prompt for a number (or quit) get a line

if the line is "quit" break out of this loop

if the line is a string of digits convert to a number store in an array otherwise print end loop compute average print the average

©2016 UMBC Training Centers 94 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Extended Example

● extended.c

1. #include 2. 3. #define MAX 100 4. #define DIGITS 1 5. #define LIMIT 100 6. 7. void getaline(char s[]); 8. int mystrcmp (char s[], char t[]); 9. int check (char s[]); 10. int myatoi (char s[]); 11. double average (int nums[], int amt); 12. 13. int main() 14. { 15. char line[MAX]; 16. int numbers[LIMIT], i = 0; 17. double answer; 18. 19. while(1) 20. { 21. printf("Enter a NUMBER (or 'quit'): "); 22. getaline(line); 23. 24. if(mystrcmp(line, "quit") == 0) { 25. break; 26. } 27. 28. if(check(line) == DIGITS) { 29. numbers[i++] = myatoi(line); 30. if(i == LIMIT) { 31. printf("ARRAY FULL!\n"); 32. break; 33. } 34. } 35. else { 36. printf("%s is not all digits\n", line); 37. } 38. } 39. 40. answer = average(numbers, i); 41. printf("%.2f\n", answer); 42. }

©2016 UMBC Training Centers 95 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

The getaline Function

● The getaline function gets a line from the keyboard and terminates with the null character. ⏵ Invoked by: getline(line); ⏵ Argument(s): a char array ⏵ Prototype is: void getline(char s[]);

● Strings are handled in C by storing them in character arrays which are terminated with the null character ­ a byte of all zero bits.

● The null character is encoded in a C program as: line[i] = '\0';

● To clarify: Although the array line has been filled, this does not mean that the function returned a value.

extended.c (continued)

43. void getaline(char s[]) 44. { 45. int i = 0; 46. char c; 47. 48. // Get a character repeatedly until you 49. // get a newline character 50. 51. while(( c = getchar()) != '\n') 52. s[i++] = c; 53. 54. s[i] = '\0'; // terminate with null character 55. }

©2016 UMBC Training Centers 96 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

The mystrcmp Function

● mystrcmp compares two strings, returning zero if strings are equal or non­zero otherwise. ⏵ Invoked by: if(mystrcmp(line, "quit") == 0) ⏵ Argument(s): two char arrays ⏵ Prototype: int mystrcmp(char s[], char t[]);

extended.c (continued)

56. int mystrcmp(char s[], char t[]) 57. { 58. int i = 0; 59. 60. // Compare a char from each array until they 61. // are different or until end of the array 62. 63. while(s[i] == t[i]) { 64. if(s[i++] == '\0') { 65. return(0); /* strings are equal */ 66. } 67. } 68. return(s[i] ­ t[i]); /* string are unequal */ 69. }

©2016 UMBC Training Centers 97 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

The check Function

● check determines if a string is all digits, returning DIGITS (value of 1) if true and !DIGITS (value of 0) otherwise. ⏵ Invoked by: if(check(line) == DIGITS) ⏵ Argument(s): a char array ⏵ Prototype is: int check(char s[]);

extended.c (cont.)

70. int check(char s[]) 71. { 72. int i = 0; 73. 74. // Loop through the string, looking for the 75. // null character 76. // If you find a non digit character, 77. // return ! DIGITS 78. 79. for (i = 0; s[i] != '\0'; i++) { 80. if(s[i] < '0' || s[i] > '9') { 81. return(! DIGITS); 82. } 83. } 84. 85. return(DIGITS); 86. }

©2016 UMBC Training Centers 98 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

The myatoi Function

● The myatoi function converts an ASCII string to an integer and returns the numeric value of the string. ⏵ Invoked by: numbers[i++] = myatoi(line); ⏵ Argument(s): a char array ⏵ Prototype: int myatoi(char s[]);

● The key code inside the myatoi function takes a char in the range '0' to '9' and converts it to a number in the range 0 to 9. The conversion is accomplished by an interesting "trick" that is often used in C: s[i++] ­ '0'

extended.c (continued)

87. int myatoi(char s[ ]) 88. { 89. int i = 0, n = 0; 90. 91. while ( s[i] >= '0' && s[i] <= '9') { 92. n = 10 * n + s[i++] ­ '0'; 93. } 94. 95. return(n); 96. }

©2016 UMBC Training Centers 99 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

The average Function

● average computes the average of the elements in an array of type int and return the average as a double. ⏵ Invoked by: answer = average(numbers, i); ⏵ Argument(s): an int array and an int ⏵ Prototype: double average(int nums[], int amt);

● Inside the average function, we assure that the returned value can contain a fractional part by using a cast: return((double) sum / amt);

extended.c (cont.)

97. double average(int nums[], int amt) 98. { 99. int i; 100. int sum = 0; 101. 102. for (i = 0; i < amt; i++) 103. sum = sum + nums[i]; 104. 105. return((double) sum / amt); 106. }

©2016 UMBC Training Centers 100 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Summary

● When functions are invoked, non­array arguments are copied to the parameters of the function. Therefore, a function cannot alter this type of argument. (This can be done with pointers ­ shown later.) void swap(int left, int right);

int main() { int a = 5, b = 10;

swap(a,b); ... }

void swap(int first, int second) { int temp;

temp = first; first = second; second = temp; }

● However, when an array is passed to a function, the parameter receives the address of the array. ⏵ Array elements are not copied. ⏵ Therefore, a function can alter the values of an array. ⏵ This allowed the getline function to work properly.

©2016 UMBC Training Centers 101 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Summary

● Functions that do not specify their return type return the type int by default.

● A function prototype, although not required, allows the compiler to assure that you do not invoke a function with the wrong number of arguments or wrong argument types.

● A function prototype specifies a return value and the types of the parameters.

● The beginning line of a function definition is similar to the function prototype except: ⏵ Identifiers (variable names) are optional in prototypes, but required in function definitions. ⏵ There is a semi­colon at the end of a prototype.

©2016 UMBC Training Centers 102 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Exercises

Note that in each of the problems listed below, you will need to write a main (driver) function to invoke the function for which the problem is designed. Also, you may have to display certain results to demonstrate that your function worked correctly.

1. Write a function which checks a string to assure that it contains only alphabetic characters there. The function must return one of two different values so you can distinguish between strings that contain only alphabetics and those that do not. The prototype for the function is: int alphacheck(char string[]);

2. C supports many varieties of the type int. Depending upon your machine, a long int will be either the same size as an int or twice as large. Write a function that receives two int's, a base and a power, and returns a long, the base raised to the power. A long int is printed with %ld. ⏵ The prototype and some skeleton code are shown below:

long power(int base, int exponent);

int main() { long int ans; int a, b; ...

ans = power(a, b); printf("%d raised to the %d power is %ld\n", a, b, ans); }

©2016 UMBC Training Centers 103 C PROGRAMMING CHAPTER 6: MORE ON FUNCTIONS

Exercises

3. Write a function that receives a string consisting of two fields and splits it into separate fields. Assume that the original string has the two fields separated by any number of blanks and tabs. The function prototype would be: void split(char input[], char out1[], char out2[]);

⏵ Some of your code may look like this:

#include

#define MAX 100

int main() { char string[MAX], field1[MAX], field2[MAX];

fgets(string, MAX, stdin); split(string, field1, field2); printf("string1: %s\nstring2: %s\n", field1, field2); }

©2016 UMBC Training Centers 104 C PROGRAMMING

Chapter 7:

Strings

©2016 UMBC Training Centers 105 C PROGRAMMING CHAPTER 7: STRINGS

Fundamental Concepts

● In C, there is no fundamental data type named string, so a string is kept as a character array. ⏵ Use the null character to mark the end of a string . '\0' ( A BYTE OF ZERO BITS)

● A string constant is coded as a sequence of characters delimited by quote symbols. ⏵ Do not confuse the string "A" with the single character 'A.' ⏵ They are of different types and have different meanings to the C compiler.

● When the compiler sees a string constant, it places the string in memory and then places the null character behind them.

● If you need to process many strings (such as sorting them), you can use a two dimensional character array.

©2016 UMBC Training Centers 106 C PROGRAMMING CHAPTER 7: STRINGS

Fundamental Concepts

● String variables are one dimensional character arrays. #define MAX 100 char string[MAX]; char word[MAX * 2]; char line[MAX + 1];

● String constants are enclosed in "quotes ". STRING LENGTH

"a\nstring" 8 "a string\n" 9 "a" 1 "" 0

● The compiler stores a string as: printf("MICHAEL");

­­­­ ­­­­ ­­­­­ ­­­­­ ­­­­­ ­­­­­ ­­­­­ ­­­­­ | 'M' | 'I' | 'C' | 'H' | 'A' | 'E' | 'L' | '\0' | ­­­­­ ­­­­­ ­­­­­ ­­­­­ ­­­­­ ­­­­­ ­­­­­ ­­­­­

● If several strings need to be processed, the following can be used. #define NO_OF_STRINGS 10 #define LENGTH 20 char lines[NO_OF_STRINGS][LENGTH + 1];

©2016 UMBC Training Centers 107 C PROGRAMMING CHAPTER 7: STRINGS

Aggregate Operations

● The compiler treats the array as the address of the place in memory where the array is kept.

● A subscripted reference is resolved by knowing two facts. ⏵ Address of the beginning of the array ⏵ Offset = subscript * sizeof(item) char line[100] = "some stuff....."; line[6] = 'A';

● The last statement is a reference to the sixth byte of memory away from the base address of data.

● Because array names are addresses in memory, aggregate operations are forbidden. Instead, functions must be written to: ⏵ copy a string; ⏵ compare two strings; ⏵ etc.

● Common string functions are in the .

©2016 UMBC Training Centers 108 C PROGRAMMING CHAPTER 7: STRINGS

Aggregate Operations

● Aggregate operations on arrays are forbidden. line = word; /* Try to copy a string */ ⏵ Compiler error: Can not change the beginning address of an array

● Comparing strings if( line == word ) /* Wrong way */ do something; ⏵ They can never be equal. Addresses are compared here.

● You must write functions to do each of these. Fortunately, they already exist in the C standard library.

©2016 UMBC Training Centers 109 C PROGRAMMING CHAPTER 7: STRINGS

String Functions

● Some of the standard string functions and their prototypes are now shown. Note how a prototype serves as a documentation aid. /* Copy source to target */ void strcpy(char target[ ], char source[ ]);

/* Compare two strings */ int strcmp(char string1[ ], char string2[ ]);

/* Compute length of string */ int strlen(char string[ ]);

● strcpy is invoked with: strcpy(line,word); /* line <­ word */

● strcmp is invoked with: if (strcmp(line,word) == 0) { // code for equality } else { // code for inequality }

● Character string constants are similar to character arrays. strcpy(line, "copy me to line");

if (strcmp(line, "quit") == 0) { // code for equality }

©2016 UMBC Training Centers 110 C PROGRAMMING CHAPTER 7: STRINGS

String Functions

int strlen(char s[]) /* length of string */ { int len = 0; while (s[len] != '\0') /* End of string? */ len++; /* No */

return(len); /* Yes */ }

void strcpy(char to[], char from[]) { int i = 0;

while( from[i] != '\0') { to[i] = from[i]; i++; } to[i] = from[i]; }

/* Another version of string copy */ void strcpy(char to[], char from[]) { int i = 0;

while((to[i] = from[i]) != '\0') i++; }

/* Still another version */ void strcpy(char to[], char from[]) { int i = 0;

while(to[i] = from[i])/* End of string? */ i++; }

©2016 UMBC Training Centers 111 C PROGRAMMING CHAPTER 7: STRINGS

String Functions Example

stringfuncs.c

2. #include 3. #include 4. 5. #define MAX 100 6. 7. main() 8. { 9. char line[MAX] = "first"; 10. char text[MAX] = "second"; 11. int len; 12. 13. if (strcmp(line, text) == 0 ) 14. printf("%s and %s are equal\n", line, text); 15. else 16. printf("%s and %s are NOT equal\n", line, 17. text); 18. 19. strcpy(line, text); 20. if ( strcmp(line, text) == 0 ) 21. printf("%s and %s are equal\n", line, text); 22. else 23. printf("%s and %s are NOT equal\n", line, 24. text); 25. 26. strcat(line,text); 27. printf("Line is now: %s\n", line); 28. 29. len = strlen(line); 30. printf("Length of %s is %d\n", line, len); 31. }

©2016 UMBC Training Centers 112 C PROGRAMMING CHAPTER 7: STRINGS

Exercises

Note that all the exercises in this lab depend upon strings ending with the '\0' character.

1. Write the function reverse, which reverses a string. The prototype for reverse is: void reverse(char string[]);

Driver Program:

#define MAX 100

void reverse(char string[]); /* Prototype */

main() { char line[MAX];

fgets(line, MAX, stdin); /* Get it */ reverse(line); /* Reverse it */ printf("%s\n", line); /* Print it */ }

void reverse(char s[]) { /* You fill in this part */ }

2. Write the function changecase, which reverses the case of any alphabetic characters in a string. The other characters stay the same. The prototype is: void changecase(char string[]);

3. Write the function mystrcmp, which compares two strings. In order to distinguish between the equality and inequality cases, mystrcmp must return an int. The prototype is: int mystrcmp(char string1[], char string2[]);

©2016 UMBC Training Centers 113 C PROGRAMMING CHAPTER 7: STRINGS

Exercises

4. Write a function palindrome, which detects whether a string is the same forwards and backwards. The prototype is: int palindrome(char string[]);

⏵ Note that the palindrome function needs only to invoke some of the string functions mentioned in this chapter and the exercises for this chapter.

©2016 UMBC Training Centers 114 C PROGRAMMING

Chapter 8:

Pointers

©2016 UMBC Training Centers 115 C PROGRAMMING CHAPTER 8: POINTERS

Fundamental Concepts

● Memory is a huge array of bytes. Each byte has a number associated with it, which is called its address. A pointer variable is used to contain an address. ⏵ There are no generic pointers. ⏵ Pointers are defined to hold the address of a specific type.

● To define a pointer, precede its name with the * symbol.

● The & (address of) operator can be used to give a pointer a value.

● The following lines of code create some pointer variables and other types. int * point; /* int pointer */ int * px, * py; /* 2 int pointers */ int x, *pi; /* int, int pointer */ double *pd; /* double pointer */ char * pc, *p; /* 2 char pointers */

● You can assign a pointer a value by using the & symbol. x = 25; px = &x; /* px points to x */

px x 1000 --> 25 5000 1000

©2016 UMBC Training Centers 116 C PROGRAMMING CHAPTER 8: POINTERS

Fundamental Concepts

● Since px is a pointer to an int. It can only hold the address of an int.

● As long as px points to x, then x can be retrieved through the indirection operator *. Therefore, the following pairs of statements are equivalent. y = x; y = *px

x = 30; *px = 30;

printf("%d\n", x); printf("%d\n", *px);

● A pointer can be modified in many ways. int x, y, *px, grades[10], *py;

px = &x; /* px points to x */ printf("%d\n", *px); /* print x */

px = &y; /* px points to y */ printf("%d\n", *px); /* print y */

px = &grades[4]; /* points to grades[4] */ printf("%d\n", *px); /* print grades[4]; */

py = px; /* py points to grades[4] */

● In each of the examples above, px points to an int.

©2016 UMBC Training Centers 117 C PROGRAMMING CHAPTER 8: POINTERS

Pointer Operators and Operations

● You can access what a pointer is pointing to by using *, the indirection operator.

● The fundamental notion of pointers in C is that: if px points to x, then *px and x are synonyms

● The * operator has many different uses.

Multiplication a = b * 5; Pointer Definition int *px; Indirect Addressing y = *px

● Pointers are commonly used to: ⏵ allow a function to alter a non­array argument; ⏵ efficiently traverse arrays; ⏵ efficiently pass a large aggregate to a function; and ⏵ construct sophisticated data structures like linked lists, binary trees, and stacks.

©2016 UMBC Training Centers 118 C PROGRAMMING CHAPTER 8: POINTERS

Changing an Argument with a Function Call

● In C, arguments are sent to a function by value. This means that by default, a function cannot alter an argument that has been passed to it. void swap(int x, int y);

main() { int a = 10, b = 5;

swap(a, b); /* will not change a or b */ }

void swap(int x, int y) { int temp;

temp = x; /* changes the values */ x = y; /* of x and y, but not */ y = temp; /* a and b back in main */ }

● Values of arguments are copied to the invoked function. Parameters receive copies of the arguments.

● To alter arguments sent to a function, the addresses of the arguments must be passed. Therefore, the parameters must be pointers.

©2016 UMBC Training Centers 119 C PROGRAMMING CHAPTER 8: POINTERS

Changing an Argument with a Function Call

● swap should be coded as follows: swap.c

1. #include 2. 3. void swap(int *x, int *y); 4. 5. main() 6. { 7. int a = 10, b = 5; 8. 9. printf("BEFORE: %d %d\n", a, b); 10. 11. swap(&a, &b); /* pass addresses */ 12. 13. printf("AFTER: %d %d\n", a, b); 14. } 15. 16. void swap(int *x, int *y) /* pointers */ 17. { 18. int temp; 19. 20. temp = *x; 21. *x = *y; 22. *y = temp; 23. }

● The above code accesses a and b indirectly through the pointers x and y. In fact, each of the following calls to this version of swap will exchange two integers: int numbers[MAX], values[MAX], a, b;

swap(numbers, values); swap(&numbers[0], &values[0]); swap(numbers + 5, values + 2); swap(&numbers[5], &values[2]); swap(&numbers[3], &a);

● In each case, two addresses are passed to swap.

©2016 UMBC Training Centers 120 C PROGRAMMING CHAPTER 8: POINTERS

Pointer Arithmetic

● A common use of pointers in C is to use them to traverse an array. An array is a collection of elements of a particular type. Pointing to the beginning of an array is as simple as pointing to any single element. int numbers[5], *px; px = &numbers[0];

px numbers 0 1 2 3 4 1000 --->

1000

*px == numbers[0]

● Recall that array names are addresses and therefore, the following is always true. &numbers[0] == numbers

● Whenever a pointer and an int occur in an expression, pointer arithmetic is performed. In pointer arithmetic, the int is scaled by the sizeof what the pointer points to.

©2016 UMBC Training Centers 121 C PROGRAMMING CHAPTER 8: POINTERS

Pointer Arithmetic

● Since arrays are addresses, each of the following is correct. (a) px = &numbers[0]; (b) px = numbers; (c) px = numbers + 0;

● Generalizing (a) and (c) yields the equivalence: &numbers[i] == numbers + i;

● The above is an example of pointer arithmetic. Here are some other examples. pointer + int pointer ­ int pointer ­ pointer (both pointers must be of same type)

©2016 UMBC Training Centers 122 C PROGRAMMING CHAPTER 8: POINTERS

Array Traversal

● Adding one to a pointer moves the pointer to the next element in an array. Therefore, this addition is only sensible if the pointer points inside an array.

● In array processing, the pointer variable successively is assigned higher and higher addresses as it moves deeper into the array.

● The test for loop completion must assure that the pointer does not point beyond the array.

● In the loop below, pointer arithmetic occurs in two places. #define MAX 10 int sum = 0, *px, numbers[MAX]; for ( px = numbers; px < numbers + MAX; px++) sum += *px; 1) Test for array completion.

⏵ numbers + max is the address of the first byte outside the array numbers. Therefore, px still points inside the array as long as: px < numbers + MAX ⏵ The loop test fails when px == numbers + MAX.

2) The px++ expression advances px to the next array element.

©2016 UMBC Training Centers 123 C PROGRAMMING CHAPTER 8: POINTERS

Array Traversal

● In a table lookup, it is easy to test for early loop exit. int numbers[MAX];

for ( px = numbers; px < numbers + MAX; px++) if(*px == specific_value) break;

if( px == numbers + MAX) printf("NOT FOUND\n"); else printf("FOUND\n");

● You could also step through from the bottom element back up toward the top. This is a good example to test your knowledge of pointers. for (px = numbers + MAX ­ 1; px >= numbers; px­­) sum += *px;

⏵ px points initially to last element. ⏵ px­­ moves px to an earlier element of the array. ⏵ px >= numbers tests to see if px still points inside the array. ⏵ When the loop test fails, the following is true: px == numbers ­ 1

©2016 UMBC Training Centers 124 C PROGRAMMING CHAPTER 8: POINTERS

Array Traversal

● Array processing with pointers always involves: ⏵ Setting a pointer to an array element ⏵ Testing to assure the pointer is still pointing inside the array ⏵ Indirectly accessing the array element through the pointer ⏵ Modifying the pointer and repeating these steps

● These points can be illustrated again by using any data type, say an array of type char. char let, *pc, wd[MAX];

● Accessing elements with character pointer pc = &let; /* pc points to let */ putchar(*pc); /* display letter */ pc = wd; /* pc points to wd[0] */ putchar(*pc) /* display wd[0] */

● The two expressions below are never the same! pc is an address (1002 in the diagram) and *pc is the character at that address (a in the diagram). char *pc, let = 'A' pc = &let;

pc let 1002 --> A 1000 1002

©2016 UMBC Training Centers 125 C PROGRAMMING CHAPTER 8: POINTERS

Array Traversal

● We now demonstrate traversal through char arrays.

● Remember, when a pointer (say pc) points to a variable, (say let), then: *pc == let

● In practice, character pointers often point to the beginning of an array of characters. char *pc, line[MAX]; int len;

gets(line); /* get a line from the keyboard */ pc = line; /* pc points to line[0] */ len = 0;

while (*pc != '\0') /* end of string? */ { len++; /* NO */ pc++; } /* YES */

printf("%d is length of %s\n", len, line);

©2016 UMBC Training Centers 126 C PROGRAMMING CHAPTER 8: POINTERS

String Functions with Pointers

● The details from the previous example could be placed inside a function. mystrlen.c

1. #include 2. 3. #define MAX 100 4. 5. int strlen(char *s); 6. 7. main() 8. { 9. char line[MAX], len; 10. 11. fgets(line, MAX, stdin); /* get input */ 12. len = strlen(line); /* invoke strlen */ 13. 14. printf("%d is length of %s\n", len, line); 15. } 16. 17. int strlen(char *s) /* s points to line */ 18. { 19. int ct = 0; 20. 21. while(*s != '\0') 22. { 23. s++; 24. ct++; 25. } 26. return(ct); 27. }

● When the function is invoked, s automatically points to line due to the argument­parameter relationship.

©2016 UMBC Training Centers 127 C PROGRAMMING CHAPTER 8: POINTERS

String Functions with Pointers

● As the pointer s is incremented, it points at successive elements of line. Ultimately, it points at the end­of­string character ­ i.e., the null character ('\0'). At that point, the expression below is false: *s != '\0'

● Actually, the tests below are equivalent: while(*s) while(*s != '\0')

©2016 UMBC Training Centers 128 C PROGRAMMING CHAPTER 8: POINTERS

Pointer Difference

● In order to illustrate pointer difference, we show another version of strlen. int strlen(char *s) { char *p; /* define another pointer */ p = s; /* p, s point to line */ while(*p) /* move p to end of string */ p++;

return(p ­ s); }

● The pointer p is initially given the value of s, so both p and s point to the beginning of the string passed to the function. p is ultimately advanced to the end of the string. Therefore, the subtraction tells how far they are apart ­ i.e., the number of characters between them.

● Note that pointer difference has a hidden scaling factor. There is an implied division by the sizeof what the pointers point to. int howmany, grades[100], *pb, *pe;

pb = &grades[0]; pe = &grades[50]; howmany = pe ­ pb; /* howmany = 50 */

©2016 UMBC Training Centers 129 C PROGRAMMING CHAPTER 8: POINTERS

Prototypes for String Functions

● The correct prototype for strlen is: int strlen(char *s);

● This matches the opening part of the definition for the function strlen. int strlen(char *s) { // function body }

● All of the prototypes below are equivalent. int strlen(char s[]); int strlen(char *s); int strlen(char *); int strlen(char []);

● Prior to this section, when we sent an array to a function, we coded the beginning part of the function and the prototype differently than above. int strlen(char s[]) { int i = 0;

while(s[i] != '\0') i++;

return(i); }

● For a parameter representing a string array, the following are equivalent and synonymous: char *s char s[]

©2016 UMBC Training Centers 130 C PROGRAMMING CHAPTER 8: POINTERS

Relationship Between an Array and a Pointer

● Can we use a subscript on a pointer?

● Can we use pointer notation on an array? ⏵ The answer to both questions is yes.

● Whenever the compiler sees a subscript, it converts the code to pointer notation. This is also why a pointer can be subscripted.

● Below is an example of subscripting through an array. int numbers[MAX], i;

for ( i = 0; i < MAX; i++) numbers[i] = 0;

● We can rewrite it using what we know about addresses. for ( i = 0; i < MAX; i++) *(numbers + i) = 0;

(numbers + i) is an address.

*(numbers + i) is the value at the address.

©2016 UMBC Training Centers 131 C PROGRAMMING CHAPTER 8: POINTERS

The Pointer Notation *p++

● Recall that array processing usually consists of: ⏵ Referencing an array element ⏵ Incrementing an index or a pointer in order to reference the next array element ⏵ Repeating until all elements are processed.

● Because arrays are usually processed with pointers, and because the steps above are so common, C provides a compact notation to perform both the processing and the incrementing. *p++

● The above expression evaluates to *p, but after that value is used, p is then incremented to point to the next element in the array.

● So *p++ is simply a terse notation for *p followed by p++.

©2016 UMBC Training Centers 132 C PROGRAMMING CHAPTER 8: POINTERS

The Pointer Notation *p++

● Consider the strcpy function: char line[MAX * 2], text[MAX];

gets(line); strcpy(text, line);

● The prototype for strcpy is: void strcpy(char *to, char *from);

● The strcpy function could be written as: void strcpy(char *s, char *t) { while(*s = *t) /* copy *t to *s */ { s++; /* increment s */ t++; /* increment t */ } }

● Or using the more compact notation, it could be written as: void strcpy(char *s, char *t) { while(*s++ = *t++); }

● The above notation might look confusing at first, but it is among the most commonly used C idioms.

©2016 UMBC Training Centers 133 C PROGRAMMING CHAPTER 8: POINTERS

Exercises

1. Rewrite the average function from Chapter 6 by changing the interface to: void average(int numbers[], int amount, double *avg); ⏵ In other words, the new function provides an additional argument, which is the recipient of the average.

2. Write the function stats which computes the mean and the variance of the elements in an array. void stats(int *nums, int sz, double *mean, double *var); ⏵ (The variance is the sum of the squared differences between the mean and each element of the array.)

3. Rewrite the string functions from Chapter 7 by using only pointer notation inside the functions. (a) Write the function reverse.

void reverse(char *string);

(b) Write the function changecase.

void changecase(char *string);

(c) Write the function strcmp.

int mystrcmp(char *string1, char *string2);

©2016 UMBC Training Centers 134 C PROGRAMMING CHAPTER 8: POINTERS

Exercises

4. An acronym of a phrase is a word made up of the capitalized first letters of each word in the phrase. For instance, NATO is the acronym for "North Atlantic Treaty Organization". Write a function that takes a phrase as its argument, and returns an acronym of that phrase. ⏵ The words "and", "the", "for", and "of" ("The United States of America") should be ignored (USA).

©2016 UMBC Training Centers 135 C PROGRAMMING CHAPTER 8: POINTERS

This Page Intentionally Left Blank

©2016 UMBC Training Centers 136 C PROGRAMMING

Chapter 9:

Structures

©2016 UMBC Training Centers 137 C PROGRAMMING CHAPTER 9: STRUCTURES

Fundamental Concepts

● A structure is a data type, which is defined by the programmer. It is an aggregate data type, which means it has many component members.

● Structure members can be of any type, whereas an array (which is also an aggregate) must have its members be of the same type.

● Many objects in the real word can be modeled using a structure. ⏵ A payroll record ⏵ An operating system task ⏵ A window on a graphics terminal display

● Programs using structures are more readable since they closely model the real world problems they are solving.

● Before you can use a structure, you must do the following. ⏵ Describe the structure to the compiler. Header files are usually used for this purpose. ⏵ Instantiate the structure.

● Structure descriptions must be made visible to any function needing to define them. This is usually accomplished by including the header file in any program needing this structure type.

©2016 UMBC Training Centers 138 C PROGRAMMING CHAPTER 9: STRUCTURES

Describing a Structure

● A structure description consists of the following. ⏵ the keyword struct ⏵ an optional tag (a descriptive name you compose) ⏵ a opening curly brace { ⏵ a set of declarations which define the created type ⏵ a closing curly brace } ⏵ a semi­colon ;

● A structure description is typically placed in a header file. The header file is typically named for the structure, which it contains. Often the header will also have some definitions used in the same application as the structure.

employee.h

2. #define BANKSIZE 100 3. #define NAMESIZE 21 4. 5. struct employee{ 6. char name [NAMESIZE]; 7. double pay; 8. char dept; 9. };

● Any file wishing to deal with an employee would then include the above file.

©2016 UMBC Training Centers 139 C PROGRAMMING CHAPTER 9: STRUCTURES

Creating Structures

● Structures are defined like any other types. The description (typically kept in a header file) merely creates a new type, struct employee in this case.

● Once the description is in , instances may be defined, as shown in the program segment below: #include "employee.h"

main() { /* Define two struct employee types and two int types */ struct employee user, worker; int a, b; }

● One program may include as many structure types as you need.

● A structure may have another structure as a member ­ i.e., nested structures: struct point { int x; int y; };

struct rectangle { struct point upper_left; struct point lower_right; }; ©2016 UMBC Training Centers 140 C PROGRAMMING CHAPTER 9: STRUCTURES

Operations on Structures

● Only a few operations are defined for structures: ⏵ You can access a structure member. ⏵ You can assign one structure to another, provided that they are the same type. ⏵ You can take the address of a structure.

● Note that it is illegal to perform the following test: if (structure1 == structure2 )

● Structure members are accessed using the dot (.) operator. #include "employee.h"

main() { struct employee user, worker; struct employee *pe;

user.pay = 3000.0; user.dept = 'M'; strcpy(user.name, "Susan");

worker = user;

pe = &worker; }

● Note that in the above code, pe is a pointer to a struct employee structure.

©2016 UMBC Training Centers 141 C PROGRAMMING CHAPTER 9: STRUCTURES

Functions Returning Structures

● We now present a series of programs, which handle various aspects of programming with structures. The first program uses a function that creates a structure and then returns it to the calling function. getrec.c

1. #include 2. #include 3. 4. #include "employee.h" 5. 6. struct employee get_rec(void); 7. 8. main() 9. { 10. struct employee user, worker; 11. 12. worker = get_rec(); 13. user = get_rec(); 14. } 15. 16. struct employee get_rec() 17. { 18. struct employee temp; 19. char line[100]; 20. 21. printf("Enter employee name: "); 22. fgets(temp.name, NAMESIZE, stdin); 23. 24. printf("Enter employee pay: "); 25. temp.pay = atof(fgets(line, 100, stdin)); 26. 27. printf("Enter employee department: "); 28. fgets(line, 100, stdin); 29. temp.dept = line[0]; 30. 31. return(temp); 32. }

©2016 UMBC Training Centers 142 C PROGRAMMING CHAPTER 9: STRUCTURES

Functions Returning Structures

● Since a structure can be assigned to another structure of the same type, you can also assign to a structure the return value of a function as long as the function is returning a structure of a compatible type. struct employee worker, user;

worker = user; worker = get_rec(); // get_rec() returns a // struct employee // structure

● This is similar to: char line[100]; int len, size;

gets(line); len = size; len = strlen(line);

● It is also permissible to pass a structure to a function.

©2016 UMBC Training Centers 143 C PROGRAMMING CHAPTER 9: STRUCTURES

Passing Structures to Functions

● When a structure is sent to a function, it is copied to the parameter. The parameter must therefore be a structure of the same type. For example: void put_rec(struct employee);

main() { struct employee worker;

worker = get_rec(); put_rec(worker); }

void put_rec(struct employee p) { printf("%s%.2f%c", p.name, p.pay, p.dept); }

● This can cost a great deal of execution time. It is more efficient to pass the address of the structure rather than the structure itself. If the address of a structure is sent to a function, then the parameter must be a pointer to this structure type.

● The same principle applies to the get_rec function. Both of these functions should be rewritten using pointers. We call these new functions output and fill.

©2016 UMBC Training Centers 144 C PROGRAMMING CHAPTER 9: STRUCTURES

Pointers to Structures

● When a function is passed the address of a structure, the parameter should be a pointer to a structure of the same type. The invocation of the output function is: output(&worker);

● The prototype becomes: void output(struct employee *p);

● The function body becomes: void output(struct employee *p) { printf("%20s %10.2f %c\n", p­>name, p­>pay, p­>dept); }

● To refer to a structure member through a pointer to a structure, use the following notation: p ­> pay

● This is in contrast to referring directly to a structure member with the dot notation: worker.pay

©2016 UMBC Training Centers 145 C PROGRAMMING CHAPTER 9: STRUCTURES

Pointers to Structures

● Our program now looks like this: getandput.c

1. #include 2. #include 3. 4. #include "employee.h" 5. 6. main() 7. { 8. struct employee worker, user; 9. 10. worker = get_rec(); 11. put_rec(worker); 12. 13. fill(&user); 14. output(&user); 15. } 16. 17. struct employee get_rec() 18. { 19. // same as in getrec.c 20. } 21. 22. void fill(struct employee *temp) 23. { 24. char line[100]; 25. 26. printf("Enter employee name: "); 27. fgets(temp ­> name, NAMESIZE, stdin); 28. 29. printf("Enter employee pay: "); 30. temp ­> pay = atof(fgets(line, 100, stdin)); 31. 32. printf("enter employee department "); 33. fgets(line, 100, stdin); 34. temp ­> dept = line[0]; 35. } 36.

©2016 UMBC Training Centers 146 C PROGRAMMING CHAPTER 9: STRUCTURES

Pointers to Structures

getandput.c

37. void put_rec(struct employee p) 38. { 39. printf("%20s %10.2f %c\n", 40. p.name, p.pay, p.dept); 41. } 42. 43. void output(struct employee *p) 44. { 45. printf("%20s %10.2f %c\n", 46. p­>name,p­>pay,p­>dept); 47. }

● It is vital to understand the difference between a structure and a structure pointer. A pointer occupies enough memory for an address, whereas a structure occupies enough memory for the data of the structure.

©2016 UMBC Training Centers 147 C PROGRAMMING CHAPTER 9: STRUCTURES

Pointers to Structures

● Do not confuse a structure with a pointer to one. They are never the same. struct employee worker, *p;

p = &worker;

/* The arrow notation is used for selecting a member through a pointer to a structure */ p ­> pay = 4500.00; /* correct */ p ­> dept = 'A'; /* correct */ p.dept = 'A'; /* WRONG */

/* The dot is used for selecting a structure member from an actual structure */ worker.pay = 4500.00; /* correct */ worker.dept = 'A'; /* correct */ worker ­> dept = 'A'; /* WRONG */

©2016 UMBC Training Centers 148 C PROGRAMMING CHAPTER 9: STRUCTURES

Array of Structures

● A common and useful data structure is an array of structures. In the declaration shown below, w is a single structure while bank is an array of structures. struct employee w, bank[100];

● Here is an example using an array of structures: pointers.c

1. #include 2. #include "employee.h" 3. 4. main() 5. { 6. struct employee bank[BANKSIZE]; 7. 8. fill_emp(bank, BANKSIZE); 9. print(bank, BANKSIZE); 10. } 11. 12. void fill_emp(struct employee *p, int size) 13. { 14. int i; 15. 16. for (i = 0; i < size; i++) 17. fill(&p[i]); 18. } 19. 20. void print(struct employee *p, int size) 21. { 22. int i; 23. 24. for (i = 0; i < size; i++) 25. output(&p[i]); 26. } 27. 28. // functions fill and output as shown previously 29.

©2016 UMBC Training Centers 149 C PROGRAMMING CHAPTER 9: STRUCTURES

Array of Structures

● Note that in both functions above, the pointer p points to the beginning of bank. Therefore, p[i] is the ith structure in the bank and &p[i] is the address of the ith structure in the bank. Note also that in the for­loops in those functions, &p[i] could be replaced with p++.

©2016 UMBC Training Centers 150 C PROGRAMMING CHAPTER 9: STRUCTURES

Functions Returning a Pointer to a Structure

● The final illustration in this section demonstrates a function named lookup, which searches an array of structures in order to find a particular one. If it is found, the function returns its address. Otherwise, the function returns NULL.

● Before we look at that example, it may be helpful to show what the employee.h file would look like with the function prototypes added.

employee.h

1. #define BANKSIZE 2 2. #define NAMESIZE 21 3. 4. struct employee{ 5. char name[NAMESIZE]; 6. double pay; 7. char dept; 8. }; 9. 10. struct employee get_rec(void); 11. void put_rec(struct employee emp); 12. 13. void fill(struct employee *p); 14. void output(struct employee *p); 15. 16. void fill_emp(struct employee *array, int size); 17. void print(struct employee *array, int size); 18. 19. struct employee *lookup 20. (char *name, struct employee *array, int size); 21.

©2016 UMBC Training Centers 151 C PROGRAMMING CHAPTER 9: STRUCTURES

Functions Returning a Pointer to a Structure lookup.c

1. #include 2. #include 3. 4. #include "employee.h" 5. 6. main(int argc, char **argv) 7. { 8. struct employee bank[BANKSIZE]; 9. struct employee *ans; 10. 11. fill_emp(bank, BANKSIZE); 12. 13. while( ­­argc > 0) 14. { 15. ans = lookup(*++argv, bank, BANKSIZE); 16. 17. if(ans == NULL) 18. printf("%s NOT FOUND\n", *argv); 19. else 20. output(ans); 21. } 22. } 23. 24. struct employee * lookup 25. (char *s, struct employee *t, int sz) 26. { 27. while( sz­­ > 0 ) 28. if(strcmp(s, t++ ­> name) == 0) 29. return(­­t); 30. 31. return(NULL); 32. } 33. 34. // Other functions as shown previously 35.

©2016 UMBC Training Centers 152 C PROGRAMMING CHAPTER 9: STRUCTURES

Exercises

1. Define a money structure, which consists of two ints called dollars and cents. Write functions to: a) Initialize a money structure b) Input a money structure from the user c) Add two money structures d) Print a money structure

Prototypes for a few of the functions are:

struct money init(int dollars, int cents); struct money add(struct money a, struct money b);

A small program using the functions above might be:

main() { struct money a = init(5,10); struct money b,c;

b = input(); /* get struct money from user */ c = add(a,b); /* add two struct moneys */ print(c); /* print the result */ }

2. Rewrite add from (1) by using the following interface. void add2 (struct money a, struct money b, struct money *c);

3. Write a function sort which sorts an array of struct employee structures. void sort(struct employee [] array, int sz);

©2016 UMBC Training Centers 153 C PROGRAMMING CHAPTER 9: STRUCTURES

This Page Intentionally Left Blank

©2016 UMBC Training Centers 154 C PROGRAMMING

Chapter 10:

File I/O

©2016 UMBC Training Centers 155 C PROGRAMMING CHAPTER 10: FILE I/O

System Calls vs. Library Calls

● The command line processor has helped with file I/O so far.

● What if we needed to process many input or output files?

● There are generally two choices for I/O statements. ⏵ Host operating system (OS) calls • Bind your program to the host OS • Non portable ⏵ Standard C library calls • Portable

● I/O is accomplished by using a set of calls, which act as an agent between your program and the OS.

● Your program makes requests to: ⏵ open; ⏵ close; ⏵ read; and ⏵ write.

● The Operating System manages the data structures and shuttles the data to and from the disk.

©2016 UMBC Training Centers 156 C PROGRAMMING CHAPTER 10: FILE I/O

Opening Disk Files

● The Operating System limits the number of files that can be opened concurrently by a single program. There is no limit to the number of files your program can process.

● A file must be opened before it can be processed. The standard library function fopen requests the operating system to open a file. FILE *fopen(char *filename, char *mode);

● The first argument is a string containing the name of the file to be opened, and the second argument is a string containing the modes with which the file is open.

● Possible modes are: Mode Open File For: Comments

"r" read Error if file does not exist

"w" create Truncate file if already exists

"a" append Write at end of file

"r+" read and write Error if does not exist

"w+" read and write Truncated if exists

"a+" read and write Only at end of file

©2016 UMBC Training Centers 157 C PROGRAMMING CHAPTER 10: FILE I/O

fopen

● Any of the modes can also have the character b for binary read and write (see next chapter). ⏵ Common for reading and writing structures ⏵ Not necessary on UNIX

● fopen returns a file pointer or NULL if it fails. The returned file pointer points inside an array of structures managed by the Operating System. Each element of this array holds information about an opened file.

● You must provide a FILE * variable to receive the returned value from fopen. It is this variable, which is presented to all I/O statements. Therefore, the file pointer connects your program to the actual disk file.

● Typically, the FILE * is a in stdio.h.

©2016 UMBC Training Centers 158 C PROGRAMMING CHAPTER 10: FILE I/O

fopen

● Here are some examples using fopen. FILE *fp; char fname[256]; char mode[20];

/* open a file named junk for reading */

fp = fopen("junk", "r");

/* open a file named on the command line for writing */ fp = fopen(argv[1],"w");

/* File name can contain Path information: Be careful on Windows machines! */ fp = fopen("/usr/include/stdio.h","r");

/* request file name interactively */ printf("enter a filename "); gets(fname); /* User supplies name */ printf("enter the mode "); gets(mode); /* User supplies mode */ fp = fopen(fname, mode);

©2016 UMBC Training Centers 159 C PROGRAMMING CHAPTER 10: FILE I/O

fopen

● The fopen function returns NULL upon failure. Here are some reasons for failure. ⏵ You do not have permission for this type of access. ⏵ The program wide file table is full. ⏵ The file is not there (open for "r").

● Failures often result from spelling errors.

● The fopen return value should always be checked against NULL. /* possible spelling error */ fp = fopen("myfil", "r"); if( fp == NULL) { printf("couldn't open 'myfil'\n"); exit(1); } OR

if ((fp = fopen("myfile", "r")) == NULL) printf("couldn't open 'myfile'\n"); exit(1); }

● You can perform allowable I/O operations on a file after you have opened the file. Of course, you should never perform I/O until you have also checked for errors as above.

● I/O is performed by a group of function calls, each of them will have the file pointer as an argument.

©2016 UMBC Training Centers 160 C PROGRAMMING CHAPTER 10: FILE I/O

I/O Library Functions

● Below is a list of library functions each of which is capable of handling input (or output) from (to) the disk. /* Input Functions */ c = getc(fp); fgets(line,MAX,fp); fscanf(fp,"formats",items);

/* Output Functions */ putc(c, fp); fputs(line,fp); fprintf(fp,"formats", items);

● The functions above perform I/O on the file associated with the file pointer, given as an argument. All of the functions above assume that there has been a previous successful fopen call.

● Each of the above functions has a direct analog with a function dedicated to either the standard input or standard output. For example: fgets(line, MAX, fp) vs. gets(line)

● The file stdio.h defines three constants of type FILE *. You can use these constants in the above functions to read the standard files. stdin Used with any input function stdout Used with any output function stderr Used with any output function

©2016 UMBC Training Centers 161 C PROGRAMMING CHAPTER 10: FILE I/O

Copying a File fopen­demo.c

1. #include 2. #include 3. 4. main(int argc, char **argv) 5. { 6. FILE *fpin, *fpout; 7. int c; 8. 9. // Make sure argument count is correct 10. 11. if ( argc != 3) { 12. fprintf(stderr, "usage:copy in out\n"); 13. exit(1); 14. } 15. 16. fpin = fopen(argv[1], "r"); 17. 18. // Make sure input file is opened 19. 20. if (fpin == NULL) { 21. fprintf(stderr, "error: %s\n",argv[1]); 22. exit(2); 23. } 24. 25. fpout = fopen(argv[2], "w"); 26. 27. // Make sure output file is opened 28. 29. if (fpout == NULL) { 30. fprintf(stderr,"error %s\n", argv[2]); 31. exit(3); 32. } 33. 34. while(( c = getc(fpin)) != EOF) 35. putc(c, fpout); 36. 37. fclose(fpin); 38. fclose(fpout); 39. 40. exit(0); 41. }

©2016 UMBC Training Centers 162 C PROGRAMMING CHAPTER 10: FILE I/O

Character Input vs. Line Input

● You can read the input a character at a time or a line at a time. The above code reads a character at a time. You can use fgets to read a line at a time.

● fgets is somewhat like gets but more capable. ⏵ Will not overwrite the array ⏵ Can read from any file (not just stdin) ⏵ Retains the newline character ⏵ Returns NULL at end­of file

● You can make the above program read a line at a time by replacing the loop above with the following one. Of course, you also need a character array to store each line as you read it. #define MAX 100

char line[MAX];

while((fgets(line, MAX, fpin)) != NULL) fputs(line, fpout);

©2016 UMBC Training Centers 163 C PROGRAMMING CHAPTER 10: FILE I/O

scanf

● The scanf function can be used to read input. This function scans the input using whitespace (blanks, tabs, and ) as the separator between input items.

● This function returns the number of correctly matched (data to format) items or EOF on end of file. This constant is defined in stdio.h.

● scanf is useful in program development where you need not be concerned with the input to your program. (You are more concerned with the logic of the program, but you still need some input to test this logic.) However, in production code, it is not as helpful because error checking is difficult with scanf.

● It is also useful when you need to input more than one value on a single line. For example: int a, b; printf("Enter age and height in inches: "); scanf("%d %d", &a, &b);

int years; double interest; char name[20]; printf("Enter name, interest and years: "); scanf("%s %lf %d", name, &interest, &years);

● The control string governs how much data is to be read and specifies the type of the data. This is similar to printf. However, scanf must use addresses of the input variables since it is attempting to alter them.

©2016 UMBC Training Centers 164 C PROGRAMMING CHAPTER 10: FILE I/O

scanf

● There are different varieties of scanf functions. char info[100]; char name[NAMESIZE]; int x = 20; FILE *fp;

/* get data from the standard input */ scanf("%s %d", name, &x);

/* get data from a disk file */ fscanf(fp, "%s %d", name, &x);

/* get data from a string */ sscanf(info, "%s %d", name, &x);

● sscanf is very useful in problems such as: int number; char line[MAX]; char name[NAMESIZE]; char dum[DUMMYSIZE];

printf("Enter a name and a number: "); fgets(line, MAX, stdin); n = sscanf(line,"%s %d %s",name, &number, dum); if( n != 2) fprintf(stderr, "badly formatted data\n");

● The above code reads the entire line, separates them into fields with sscanf, and then performs error checking.

©2016 UMBC Training Centers 165 C PROGRAMMING CHAPTER 10: FILE I/O

scanf

● While scanf does not provide robust error checking, it is safe to use if you need to input string information.

● This program prints words from standard input, one word per line.

scanf­demo.c

1. #include 2. 3. #define WORDSIZE 40 4. 5. int main() 6. { 7. char word[WORDSIZE]; 8. int word_number = 1; 9. 10. while(scanf("%s", word) != EOF) { 11. printf("%d %s\n", word_number++, word); 12. } 13. }

©2016 UMBC Training Centers 166 C PROGRAMMING CHAPTER 10: FILE I/O

fprintf

● Like scanf, the printf function has several variations.

● printf sends data to the standard output.

● fprintf sends data to the file associated with the file pointer used as the first argument. fp = fopen("file", "r+"); /* read/write */

/* Send data to file associated with 'fp' */ fprintf(fp, "data %d\n", x);

fprintf(stderr, "error on file1\n");

● sprintf sends the data to the string given as the first argument. char temp1[10], temp2[20]; char info[100], string[100]; int x = 20, number, len;

/* Send data to the string 'info' */ sprintf(info, "data %d\n", x);

/* Gluing non­string data together */ strcpy(temp1, "hello"); strcpy(temp2, "goodbye"); number = 356; sprintf(string, "%s%d%s", temp1, number, temp2);

len = strlen(string); /* len = 15 */

©2016 UMBC Training Centers 167 C PROGRAMMING CHAPTER 10: FILE I/O

fclose

● There is a limit to the number of files that can be opened at the same time. Trying to open too many causes fopen to fail.

● To the operating system, opening a file means a "slot" is occupied in a data structure. When you are finished processing a file, you should close the file to free this slot.

● The function fclose is provided for this. Another function, fcloseall, closes all open files. fclose­demo.c

1. #include 2. 3. int main(int argc, char **argv) 4. { 5. FILE *fp; 6. int c, ct = 0; 7. while ( ­­argc > 0 ) 8. { 9. fp = fopen(*++argv, "r"); 10. if ( fp == NULL) 11. { 12. fprintf(stderr, "err on %s\n",*argv); 13. continue; 14. } 15. 16. ct = 0; 17. while ((c = getc(fp)) != EOF) 18. if (c == '\n') 19. ct++; 20. 21. fclose(fp); 22. printf("%d %s\n", ct, *argv); 23. } 24. }

©2016 UMBC Training Centers 168 C PROGRAMMING CHAPTER 10: FILE I/O

Servicing Errors – errno.h

● When fopen fails, you can find the exact reason for the failure, because the system variable errno is set to an error code.

● You can use errno as an argument to the function strerror to see the exact reason for the failure. errno must be defined by the declaration shown in bold.

errno­demo.c

1. #include 2. #include 3. #include 4. #include 5. 6. int main(int argc, char **argv) 7. { 8. extern int errno; 9. FILE *fp; 10. 11. fp = fopen(argv[1], "r"); 12. if ( fp == NULL ) { 13. printf("%s: %s\n", argv[0], strerror(errno)); 14. exit(errno); 15. } 16. 17. exit(0); 18. }

● Here are a few sample executions of the program: $ errs /etc/shad errs: No such file or diredtory $ echo $? 2 $ errs /etc/shadow errs: Permission denied $ echo $? 13

©2016 UMBC Training Centers 169 C PROGRAMMING CHAPTER 10: FILE I/O

feof

● When certain functions, like getchar or getc, return the value –1. This value indicates either end of file or error. The function feof allows you to distinguish between these two. while(! feof(fp)) if ((c = getc(fp)) == EOF) /* Must be error */

©2016 UMBC Training Centers 170 C PROGRAMMING CHAPTER 10: FILE I/O

Exercises

1. Write the program compare, which displays information about the two files named on the command line. $ compare file1 file2 file1 and file2 are the same

$ compare file1 file3 file1 and file3 are different

2. Write the program glue which glues together files named on the command line and sends them to the display. $ cat file1 1 2

$ cat file2 3 4

$ glue file1 file2 1 2 3 4 $

3. Add a variation to (2). If the last named file on the command line is prefixed with a + symbol, then the output should go there and not to the display. $ glue file1 file2 +output $ cat output 1 2 3 4 ©2016 UMBC Training Centers 171 C PROGRAMMING CHAPTER 10: FILE I/O

Exercises

4. Write a program that displays the number of characters, words, and lines in a file named on the command line.

©2016 UMBC Training Centers 172 C PROGRAMMING

Chapter 11:

Information About Files

©2016 UMBC Training Centers 173 C PROGRAMMING CHAPTER 11: INFORMATION ABOUT FILES

The stat Function

● In many programs, the issues involve not only the data inside of a file, but also the data about a file. Each Operating System keeps track of various information about a file, such as its size, modification date, etc.

● The C programmer is given an interface to this information through the function named stat. If the file exists, this function fills up a struct stat structure with information about the file. If the file does not exist, then stat returns –1. Thus, you can also use stat to check for file existence. ⏵ Here is the prototype for stat. int stat(char *name, struct stat *buffer);

● stat takes two arguments. ⏵ a filename ⏵ the address of a struct stat variable

● The struct stat description is found in the header file stat.h, in the sys sub directory under include.

©2016 UMBC Training Centers 174 C PROGRAMMING CHAPTER 11: INFORMATION ABOUT FILES

The stat Function

● The struct stat description is shown for convenience. struct stat { short st_dev; /* device of file */ short st_ino; /* inode number */ short st_mode; /* direc+perms+other */ short st_nlink; /* number of links */ int st_uid; /* user id of owner */ int st_gid; /* group id of owner */ short st_rdev; /* */ long st_size; /* size in bytes */ long st_atime; /* last access time */ long st_mtime; /* last mod time */ long st_ctime; /* last inode mod time */ };

● On some systems, the types in the struct stat structure are typedefed. The typedefs themselves will be in the header file types.h in sys.

©2016 UMBC Training Centers 175 C PROGRAMMING CHAPTER 11: INFORMATION ABOUT FILES

File Existence

● First, we look at a program which determines if a file exists. Assume that a group of files is named on the command line. #include #include main(int argc, char **argv) { struct stat stbuf; while( ­­argc > 0 ) { if (stat(*++argv,&stbuf) == ­1) printf("%s is NOT a file\n", *argv); else printf("%s IS a file\n",*argv); } }

● We could easily modify this program so that it prints the sizes of files named on the command line. #include #include main(int argc, char **argv) { struct stat stbuf; while( ­­argc > 0 ) { if (stat(*++argv,&stbuf) == ­1) printf("%s NOT a file\n", *argv); else { printf("%s IS ", *argv); printf("%ld\n", stbuf.st_size); } } }

©2016 UMBC Training Centers 176 C PROGRAMMING CHAPTER 11: INFORMATION ABOUT FILES

Telling Time ­ time and ctime

● Each file has three times associated with it. All times are stored as the number of seconds since some epochal date (1/1/70). ⏵ This is a concise way of storing times. ⏵ It is not a good way of displaying them. ⏵ The standard library has many time functions.

● The current time is obtained with a call to time, which fills a long int with the seconds since epoch. Other functions chop up the time from time into more readable pieces.

● The ctime function reformats the time output into a string. Here is a program, which prints the time as a long integer. The following program prints the time in a more readable form. showtime.c

1. #include 2. #include 3. 4. main() 5. { 6. long int clock; 7. 8. time(&clock); 9. printf("%ld\n", clock); 10. printf("%s\n", ctime(&clock)); 11. }

©2016 UMBC Training Centers 177 C PROGRAMMING CHAPTER 11: INFORMATION ABOUT FILES

Telling Time ­ time and ctime

● ctime can be used in a variety of ways. For example, the code below prints the last modified time for any file named as a command line argument. #include #include main(int argc, char **argv) { struct stat stbuf; while( ­­argc > 0 ) { if (stat(*++argv,&stbuf) == ­1) printf("%s NOT a file\n", *argv); else { printf("%s: LAST MOD DATE",*argv); printf("%s\n",ctime(&stbuf.st_mtime)); } } }

©2016 UMBC Training Centers 178 C PROGRAMMING CHAPTER 11: INFORMATION ABOUT FILES

Telling Time – localtime

● For programs requiring finer granularities of time, you could take (e.g.) the modification time and chop it into smaller pieces (day, month, etc).

● This requires knowledge of a struct tm structure which is kept in time.h. struct tm { int tm_sec; /* seconds */ int tm_min; /* minutes */ int tm_hour; /* 0­23 from midnight */ int tm_mday; /* day of month */ int tm_mon; /* month, zero­based */ int tm_year; /* since 1900 */ int tm_wday; /* day of week, zero­based */ int tm_yday; /* julian date, zero­based */ int tm_isdst; /* daylight savings time */ };

● Here is a program using the above information. localtime.c

1. #include 2. #include 3. 4. main() 5. { 6. struct tm *pts; 7. long int clock; 8. 9. time(&clock); 10. printf("%ld\n", clock); 11. 12. pts = localtime(&clock); 13. printf("%d/%d/%d\n", pts­>tm_mon + 1, 14. pts­>tm_mday, 15. pts­>tm_year + 1900); 16. }

©2016 UMBC Training Centers 179 C PROGRAMMING CHAPTER 11: INFORMATION ABOUT FILES

Exercises

1. Write a program, which is passed several filenames on the command line. For each file, print the number of hours that have elapsed since they were last modified.

2. Using the time function, write a program that prints the date on the display and then ten seconds later prints the date again.

©2016 UMBC Training Centers 180 C PROGRAMMING

Appendix A:

Reference

©2016 UMBC Training Centers 181 C PROGRAMMING APPENDIX A: REFERENCE

Important Header Files

● Header files are listed alphabetically with names as they appear in the include directory.

⏵ assert.h assert macro for error handling ⏵ ctype.h character classification and conversion ⏵ errno.h system error numbers for errno ⏵ float.h limits for non­integer constants ⏵ limits.h limits for integer constants ⏵ math.h prototypes for math functions ⏵ stdarg.h macros for functions requiring a varying number of arguments ⏵ stdio.h prototypes for I/O functions, #define's for EOF, NULL, typedef for FILE ⏵ stdlib.h prototypes for conversion functions, malloc, system, and other utilities ⏵ string.h prototypes for string functions ⏵ sys/stat.h stat structure definition ⏵ sys/types.h common typedef's ⏵ time.h prototypes fortime functions

©2016 UMBC Training Centers 182 C PROGRAMMING APPENDIX A: REFERENCE

printf Formats

● Data Type Format Explanation int %d decimal int %o octal int %x hexadecimal unsigned int %u unsigned char %c single character char * %s string float %f floating pt double %f floating pt, double precision long int %ld decimal pointer types %p address

● Each format above can have the following variations: printf("%10d\n", x); // min field width of 10 // pad with spaces // right justified

printf("%010d\n", x); // pad with zeros

printf("%­10d\n", x); // left justified

printf("%.10d\n", x); // max field width of 10 // truncate if necesssary

printf("%­10.10d\n", x); // field width of 10

● Control over the decimal point with float or double double money = 123.45;

printf("$%10.2f\n", money); // field width of 10 // 2 digits to right // of decimal point

©2016 UMBC Training Centers 183 C PROGRAMMING APPENDIX A: REFERENCE

printf Formats

● Special "escape" sequences: To Print Use

percent sign %% tab \t newline \n backslash \\ quote \" bell \a carriage return \r any octal value \0oo any hex value \xhh

©2016 UMBC Training Centers 184 C PROGRAMMING APPENDIX A: REFERENCE

C Reserved Words

⏵ auto default storage class for local variables ⏵ break exit from loops, and switch cases ⏵ case with switch ­ a specific alternative ⏵ char data type ⏵ const alternative to symbolic constants ⏵ continue inside loops: do next iteration ⏵ default error case for switch ⏵ do with while control flow construct ⏵ double data type ⏵ else with if control flow construct ⏵ enum data type ⏵ extern storage class ⏵ float data type ⏵ for control flow construct ⏵ goto alter control flow ⏵ if control flow construct ⏵ long kind of int

©2016 UMBC Training Centers 185 C PROGRAMMING APPENDIX A: REFERENCE

C Reserved Words

⏵ register store variable for speed ⏵ return return control to caller ⏵ short kind of int ⏵ signed kind of char or int ⏵ sizeof determine storage requirement ⏵ static storage class ⏵ struct create new types ⏵ switch control flow construct ⏵ typedef create new names for types ⏵ union multiple storage interpretation ⏵ unsigned bit manipulation type ⏵ void function returning nothing ⏵ volatile variable manipulated outside of program control ⏵ while control flow construct

©2016 UMBC Training Centers 186 C PROGRAMMING APPENDIX A: REFERENCE

Conversion

● char is treated as int in expressions. char let = 'A';

let++; // the char ‘B’ let ­= 'B'; // the value 0 let = getchar(); if(isupper(let)) { // if upper case let = let ­ 'A' + 'a' // convert to lower case }

● If unsigned's are not involved, the conversion rules are: long double (op) anything => long double

double (op) anything => double

float (op) anything => float

long (op) anything => long

char => int AND short => int

● Conversions between unsigned and signed are machine dependent. ⏵ Do not use unsigned unless you are doing bit manipulation. ⏵ Strings are converted to various numerical types through the use of library functions such as atof, atoi, atol.

©2016 UMBC Training Centers 187 C PROGRAMMING APPENDIX A: REFERENCE

Conversion

● strtod splits the numerical part of a string and the alphabetic part of a string into two pieces. char input[80], *endptr; double value;

strcpy(input,"123.4ABC"); value = strtod(input, &endptr); printf("%s %f %s\n",input, value, endptr);

The code above produces this output:

123.4ABC 123.400000 ABC

● The cast construct can be used to force explicit conversions. Casts are parenthesized types applied to expressions. int x = 25;

// sqrt expects a double // so cast int value to double

printf("%f\n", sqrt((double) x));

©2016 UMBC Training Centers 188 C PROGRAMMING APPENDIX A: REFERENCE

Precedence Chart

● Operators associate left to right except rows 2, 13, and 14

Row Operators

1. () [] ­> . 2. ! ~ ++ ­­ + ­ * & sizeof cast 3. * / % 4. + ­ 5. << >> 6. < <= > >= 7. == != 8. & 9. ^ 10. | 11. && 12. || 13. ? : (conditional operator ) 14. = += ­= *= /= %= 15. ,

©2016 UMBC Training Centers 189 C PROGRAMMING APPENDIX A: REFERENCE

This Page Intentionally Left Blank

©2016 UMBC Training Centers 190 C PROGRAMMING

Appendix B:

Useful Library Functions

©2016 UMBC Training Centers 191 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

strstr

● This chapter demonstrates many useful library functions. For each function we present a short description, the function prototype, and an example using the function.

● The strstr function takes two strings and determines whether the second is contained in the first.

● If it is contained in the first, the function returns a pointer to the place in the first string where the second string occurs. Otherwise, the function returns NULL. char *strstr(char *string, char *substring);

● strstr can be used to write a frail, yet useful, version of the UNIX grep utility.

©2016 UMBC Training Centers 192 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

strstr

● The code below is executed as follows: $ mygrep pattern filenames....

● After checking whether the minimum number of arguments have been supplied, the program reads each line of each file, and prints those lines matching argv[1].

mygrep.c

1. #include 2. #include 3. #include 4. 5. #define MAXLINE 100 6. 7. main(int argc, char **argv) 8. { 9. FILE *fp; 10. char line[MAXLINE]; 11. int i; 12. 13. if (argc < 3) { 14. printf("usage: mygrep pattern files..\n"); 15. exit(1); 16. } 17. 18. for (i = 2; i < argc; i++) { 19. if((fp = fopen(argv[i], "r")) == NULL) { 20. fprintf(stdout,"bad open %s\n", argv[1]); 21. } else { 22. while(fgets(line,MAXLINE,fp) != NULL) { 23. if(strstr(line, argv[1]) != NULL) { 24. printf("%s", line); 25. } 26. } 27. } 28. } 29. }

©2016 UMBC Training Centers 193 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

strchr, strrchr

● strchr (strrchr) finds the first (last) occurrence of a character within a string. Each function returns a pointer to the character, or NULL if there are no occurrences of the character. char *strchr(char *string, int character); char *strrchr(char *string, int character);

● The program on the next page takes an specified on the command line and prints its value.

● Note that this program uses the environment pointer, which behaves like argv. That is, envp is a pointer to the first of many pointers each pointing at an environment string.

©2016 UMBC Training Centers 194 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

strchr, strrchr

penv.c

1. #include 2. #include 3. #include 4. 5. #define MAXLINE 100 6. 7. main(int argc, char** argv, char** envp) 8. { 9. char *p; 10. int i; 11. 12. for (i = 0; i < 5 ; i++) { 13. printf("%s\n", envp[i]); 14. } 15. 16. printf("\n\n"); 17. 18. if(argc != 2) { 19. printf("usage: printenv var_name\n"); 20. exit(2); 21. } 22. 23. while (*envp != NULL) { 24. if (strstr(*envp, argv[1]) != NULL) { 25. p = strchr(*envp, '='); 26. printf("%s\n", p + 1); 27. exit(0); 28. } 29. ++envp; 30. } 31. 32. printf("%s: not in env\n", argv[1]); 33. exit(1); 34. }

©2016 UMBC Training Centers 195 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

system

● system enables you to execute an operating system command line from your C program. int system(char *command_string);

● You could use system as the skeleton for a command line processor. char line[MAXLINE]; int res;

while(1) { printf("=> "); fgets(line, MAXLINE, stdin); if (strcmp(line, "logout") == 0) { break; }

system(line); }

● system is also used after you have built a command through the use of other functions. char cmd[100];

strcpy(cmd, "copy "); strcat(cmd, "filea "); strcat(cmd, "fileb"); system(cmd);

sprintf(cmd, "%s %s %s","diff","file1", "file2"); system(cmd);

©2016 UMBC Training Centers 196 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

strtok

● strtok finds sequences of characters (tokens), which are delimited by characters from a set of your choosing. char *strtok(char *string, char *delimiters);

● The first invocation of strtok contains the string that you want parsed. Subsequent invocations use the value NULL to indicate continued parsing of the same string.

● This reads a file and prints each word in the file on a new line. A word is defined as a sequence of characters delimited by any characters in the delimiter string. delim.c

1. #include 2. #include 3. 4. #define MAXLINE 100 5. 6. main () 7. { 8. char delimiters[50], line[MAXLINE], *p; 9. 10. strcpy(delimiters, "#@!+={}()*&^%\n"); 11. strcat(delimiters, "$~\\=­?/>.<,\":;'\t"); 12. 13. while(fgets(line, MAXLINE, stdin) != NULL) { 14. p = strtok(line, delimiters); 15. 16. while (p != NULL) { 17. printf("%s\n", p); 18. p = strtok(NULL, delimiters); 19. } 20. 21. printf("\n%s\n", line); 22. } 23. }

©2016 UMBC Training Centers 197 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

strspn, strcspn

● A common programming problem is data validation. ⏵ Is a string composed of chars from the same class? ⏵ Is a string devoid of alphabetics?

● These two problems are handled by the functions: int strspn(char *string, char *class); int strcspn(char *string, char *class);

● strspn (strcspn) returns the length of the prefix of string that contains only characters in (not in) class.

● For example: char line[LINESIZE], digits[] = "0123456789"; int ans;

fgets(line, LINESIZE, stdin); ans = strspn (line, digits);

/* ans indexes the first non digit */ /* if line is "1238abcd", then ans = 4 */

fgets(line, LINESIZE, stdin); ans = strcspn (line, digits);

/* ans indexes the first digit */ /* if line is "ab1234", then ans = 2 */

©2016 UMBC Training Centers 198 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

strspn, strcspn

● The following example reads strings and classifies them as all digits, no digits, or a mixture of digits and non­digits.

digits.c

1. #include 2. #include 3. 4. #define MAXLINE 100 5. 6. int main() 7. { 8. char line[MAXLINE], digits[11]; 9. int n, d, len; 10. 11. while (1) { 12. printf("Enter string "); 13. fgets(line, MAXLINE, stdin); 14. if(strcmp(line, "quit") == 0) { 15. break; 16. } 17. 18. len = strlen(line); 19. if((d = strspn(line, digits)) == len) { 20. printf("%s is all digits\n", line); 21. } 22. else if ((n = strcspn(line, digits)) == len){ 23. printf("%s has no digits\n", line); 24. } 25. else { 26. printf("%s is mixed\n", line); 27. printf("first non digit is %d\n", d + 1); 28. printf("first digit is %d\n", n + 1); 29. } 30. } 31. }

©2016 UMBC Training Centers 199 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

Math Functions

● We next illustrate a few functions from the math library. double exp(double exponent); double sqrt(double); double pow(double base, double exponent);

● On some systems, you may need to give the linker some additional instructions to search the math library. On UNIX for example, use the ­lm option. #include

int main() { int i;

printf("\tX\tE to the X\tSQRT(X)\t 2**X\n"); printf("\t­\t­­­­­­­­­­\t­­­­­­\t­­­­­­\n");

for (i = 1; i <= 10; i++) { printf("\t%3d\t%10.3f",i,exp((double) i)); printf("\t%10.3f", sqrt((double) i)); printf("\t%10.3f\n",pow(2.0, (double) i)); } }

● The output from the program is: X E to the X SQRT(X) 2**X ­ ­­­­­­­­­­ ­­­­­­­ ­­­­­­ 1 2.718 1.000 2.000 2 7.389 1.414 4.000 3 20.086 1.732 8.000 4 54.598 2.000 16.000 5 148.413 2.236 32.000 6 403.429 2.449 64.000 7 1096.633 2.646 128.000 8 2980.958 2.828 256.000 9 8103.084 3.000 512.000 10 22026.466 3.162 1024.000

©2016 UMBC Training Centers 200 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

Character Testing Functions

● The header file ctype.h contains a group of function prototypes (or macro definitions) for determining character classification. int isalpha(int); /* True if alpha */ int isdigit(int); /* True if digit */ int isupper(int); /* True if upper */ int islower(int);/* True if lower */

int tolower(int); /* upper to lower*/ int toupper(int); /* lower to upper*/

● The program below reads from standard input and converts letters to their opposite case. #include #include

int main() { int c;

while((c = getchar()) != EOF) {

if (isupper(c)) { putchar(tolower(c)); } else if (islower(c)) { putchar(toupper(c)); } else { putchar(c); } } }

©2016 UMBC Training Centers 201 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

exit and atexit

● The exit function is used to both terminate your program and send an exit value to the parent process. ⏵ Programs may be executed in a batch or script file. ⏵ Programs may be started by another program.

● The atexit function allows you to register functions so that they may be executed when your program terminates. These functions are stacked so that they execute in the reverse order of termination. #include

void fun(void); void fun2(void);

int main() { atexit(fun); atexit(fun2); exit(0); }

void fun() { printf("1\n"); }

void fun2() { printf("2\n"); }

©2016 UMBC Training Centers 202 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

signal

● A signal is a message (a small integer) sent to an executable program by the operating system.

● Signals can be initiated by: ⏵ a user (CTRL­C) ⏵ a program (ALARM) ⏵ the operating system (KILL)

● When a program receives a signal, it can respond by: ⏵ Ignoring the signal ⏵ Performing a system action (e.g., program termination) ⏵ Executing a programmer­defined signal handler

● The signal function is used to set a program response to a particular signal.

● There is no uniform support of signals among all operating systems.

● When your program begins, program termination is established as the default response for all signals.

● Each use of the signal function in your program can have the effect of changing the default response for a particular signal.

©2016 UMBC Training Centers 203 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

signal

● The prototype for signal is in signal.h. void signal(int sig_num, void(*response)(int));

● sig_num is the signal number as found in signal.h. Here are a few of them: #define SIGFPE 8 /* Floating point trap */ #define SIGILL 4 /* Illegal instruction */ #define SIGINT 2 /* User interrupt */ #define SIGSEGV 11 /* Mem access violation */ #define SIGTERM 15 /* Software Termination */

● response is the action to be taken upon receipt of this signal. The choice is among: #define SIG_DFL 0 /* Default action */ #define SIG_IGN 1 /* Ignore action */ #define SIG_ERR ­1 /* Error return */

● The second argument is a pointer to a function which takes one int argument and which returns void.

● Some uses of signal: signal(SIGINT, SIG_IGN) /* Ignore interrupt */ signal(SIGINT, fun); /* Execute fun */

©2016 UMBC Training Centers 204 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

memcpy

● The memcpy function copies n bytes from some source to some destination. void *memcpy(void *dest, void *source, int n);

#include #include

int main() { char src[] = "*****"; char des[] = "abcdefghijlkmnopqrstuvwxyz"; char *ptr;

printf("before : %s\n", des); ptr = memcpy(des, src, strlen(src));

if (ptr) { printf("after: %s\n", dest); } else { printf("memcpy failed\n"); } }

©2016 UMBC Training Centers 205 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

memset

● memset copies n occurrences of c to some destination. void *memset(void *dest, int c, int n);

#define NAMESIZE 20

struct example { char name[NAMESIZE]; int age; char dept; };

/* use memset to initialize a structure */

int main() { struct example item;

memset(&item, 0, sizeof(struct example)); … }

©2016 UMBC Training Centers 206 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

qsort

● The qsort function performs a on the data you supply. It requires four arguments. arg1 Address of the data to be sorted arg2 How many items to be sorted arg3 The sizeof each item arg4 Address of a comparison function

#include #include

int numcmp(int *a, int *b) { return(*a ­ *b); }

int qcomp(char **a, char **b) { return(strcmp(*a, *b)); }

int main(int argc, char **argv) { int i, x[10] = { 0,3,4,2,3,5,6,8,7,1};

/* Sort an array of integers */

qsort(x, 10, sizeof(int), numcmp);

/* Sort strings form the command line */

++argv; ­­argc; qsort(argv,argc,sizeof(char *),qcomp);

for(i = 0; i < argc ; i++) { printf("%s\n", argv[i]); } }

©2016 UMBC Training Centers 207 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

Binary Search – bsearch

● The bsearch function performs a binary search on an array. The array must be sorted first. bsearch returns a void * type.

● The bsearch function requires five arguments: arg1 Address of the key to be found arg2 Address of the array to be searched arg3 Number of elements in the array arg4 Sizeof each element arg5 Address of a comparison function

#include #include

int numcmp(int *a, int *b) { return(*a ­ *b); }

int main() { int i, val, *ptr, x[10] = {0,3,4,2,3,5,6,8,7,1};

qsort(x, 10, sizeof(int), numcmp); // Sort first

for (i = 1; i < argc; i++) {

val = atoi(argv[i]); ptr = bsearch(&val, x, 10, sizeof(int), numcmp);

if (ptr) { printf("%d found at %d\n",val, ptr ­ x); } } }

©2016 UMBC Training Centers 208 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

Exercises

1. Write a program to completely validate a string of the form. ...ddddd.dd

The string can have any number of leading digits, followed by a decimal point, followed by exactly two digits. Use the following as an outline for the program:

while(fgets(line, MAXLINE, stdin)) { // Process the input line and // indicate whether the line is // valid or not valid. If not // valid, state the reason.

}

©2016 UMBC Training Centers 209 C PROGRAMMING APPENDIX B: USEFUL LIBRARY FUNCTIONS

This Page Intentionally Left Blank

©2016 UMBC Training Centers 210