INTRODUCTION TO C PROGRAMMING Curso Propedeutico 2 CINVESTAVGuadalajara

  • Slides: 99
Download presentation
INTRODUCTION TO C PROGRAMMING Curso Propedeutico (2) CINVESTAV-Guadalajara Dr. Pedro Mejia Alvarez Julio 2016

INTRODUCTION TO C PROGRAMMING Curso Propedeutico (2) CINVESTAV-Guadalajara Dr. Pedro Mejia Alvarez Julio 2016

2 nd. Class: Contents 1. 2. 3. 4. 5. Arrays. Strings Control Flow Input

2 nd. Class: Contents 1. 2. 3. 4. 5. Arrays. Strings Control Flow Input and Output Data Strucutures

ARRAYS

ARRAYS

One-Dimensional Arrays • A one-dimensional array is declared in the following way: int a[10];

One-Dimensional Arrays • A one-dimensional array is declared in the following way: int a[10]; The number 10 declares that a will have ten elements. • Array bounds always start at 0, so a has the following appearance: Notice that 10 is the length of the array, not the array’s upper bound.

Array Subscripting • To select an element of an array, use the [] operator:

Array Subscripting • To select an element of an array, use the [] operator: a[0] a[i*2+1] This operation is called array subscripting.

Array Subscripting • Example of array subscripting: #include <stdio. h> #define N 100 int

Array Subscripting • Example of array subscripting: #include <stdio. h> #define N 100 int main(void) { int a[N], i, sum; printf("Enter %d numbers: ", N); for (i = 0; i < N; i++) scanf("%d", &a[i]); sum = 0; for (i = 0; i < N; i++) sum += a[i]; printf("Sum is %dn", sum); printf("Average is %dn", sum/N); return 0; }

Array Subscripting • Warning: Array bounds are not checked; when a subscript goes out

Array Subscripting • Warning: Array bounds are not checked; when a subscript goes out of bounds, the result is unpredictable. One common cause of a subscript out of bounds: forgetting that an array with n elements is indexed from 0 to n– 1, not 1 to n. On some systems, the following innocent-looking for statement causes an infinite loop: int a[10], i; for (i = 1; i <= 10; i++) a[i] = 0;

Multidimensional Arrays • Arrays may have more than one dimension: int m[5][9]; m has

Multidimensional Arrays • Arrays may have more than one dimension: int m[5][9]; m has the following appearance:

Multidimensional Arrays • An element of m is accessed by writing m[i][j]. • Example

Multidimensional Arrays • An element of m is accessed by writing m[i][j]. • Example of multidimensional array use: #define NUM_ROWS 10 #define NUM_COLS 10 int m[NUM_ROWS][NUM_COLS], row, col; for (row = 0; row < NUM_ROWS; row++) for (col = 0; col < NUM_COLS; col++) if (row == col) m[row][col] = 1; else m[row][col] = 0;

Initializing an Array • An array may be initialized at the point of definition.

Initializing an Array • An array may be initialized at the point of definition. An array initializer is a list of expressions enclosed in braces: int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; • If an initializer is too short, the remaining elements of the array are given the value 0: int a[10] = {0}; /* initial value of a is {0, 0, 0, 0} */ An initializer cannot be empty nor can it be longer than the array it initializes.

Initializing an Array • If an initializer is present, the length of the array

Initializing an Array • If an initializer is present, the length of the array may be omitted: int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; • Multidimensional arrays can be initialized: float matrix[5][3] {2. 0, {3. 0, {4. 0, {5. 0, = {{1. 0, 1. 0}, 2. 0}, 3. 0}, 4. 0}, 5. 0}};

Variable-Length Arrays (C 99 Only) • In C 99, the length of an array

Variable-Length Arrays (C 99 Only) • In C 99, the length of an array can be specified by a variable or other expression: int a[2*n+1]; An array declared in this way is said to be a variable-length array. • Variable-length arrays are only allowed in functions (including main).

Strings

Strings

String Literals • String literals are enclosed in double quotes: "Put a disk in

String Literals • String literals are enclosed in double quotes: "Put a disk in drive A, then press any key to continuen“ • A string literal may be extended over more than one line by writing immediately followed by the end of the line: printf("Put a disk in drive A, then press any key to continuen"); • A string literal may be divided into two or more shorter strings; the compiler will join these together into one string: printf("Put a disk in drive A, then " "press any key to continuen");

How String Literals Are Stored • The string literal "abc" is represented by the

How String Literals Are Stored • The string literal "abc" is represented by the three characters a, b, and c, followed by a null character (): • Like any array, a string literal is represented by a pointer to the first character in the string. • A string literal of length 1 is different from a character constant. A string literal of length 1 ("a", for example) is represented by a pointer. A character constant ('a', for example) is represented by an integer value.

How String Literals Are Stored • Warning: Don’t ever use a character constant when

How String Literals Are Stored • Warning: Don’t ever use a character constant when a string literal is required (or vice-versa). The call printf("n"); is legal, because printf expects a string as its first parameter, but printf('n'); is not.

String Variables • A string variable is just a one-dimensional array of characters: #define

String Variables • A string variable is just a one-dimensional array of characters: #define STR_LEN 80 char str[STR_LEN+1]; The array should be one character longer than the string it will hold, to leave space for the null character. • Warning: Failure to leave room for the null character may cause unpredictable results when using string-handling functions in the C library.

String Variables • A string variable can be initialized: char date 1[8] = "June

String Variables • A string variable can be initialized: char date 1[8] = "June 14"; The date array will have the following appearance: • A string initializer need not completely fill the array: char date 2[9] = "June 14"; The leftover array elements are filled with null characters:

String Variables • If the length of the array is omitted, the compiler will

String Variables • If the length of the array is omitted, the compiler will compute it: char date 3[] = "June 14"; /* date 3 is 8 characters long */

Reading and Writing Strings • To read or write a string, use scanf or

Reading and Writing Strings • To read or write a string, use scanf or printf with the %s conversion specification: scanf("%s", str); printf("%s", str); scanf skips white space, then reads characters into str until it encounters a white-space character. • No ampersand is needed when using scanf to read into a string variable. Since a string variable is an array, the name of the variable is already a pointer (to the beginning of the array).

Reading and Writing Strings • A faster alternative: Use gets and puts instead of

Reading and Writing Strings • A faster alternative: Use gets and puts instead of scanf and printf: gets(str); puts(str); gets reads characters into str until it encounters a newline character. puts prints str, followed by a new-line character. • scanf and gets automatically put a null character at the end of the input string. printf and puts assume that the output string ends with a null character.

Reading and Writing Strings • Warning: Both scanf and gets assume that the string

Reading and Writing Strings • Warning: Both scanf and gets assume that the string variable is large enough to contain the input string (including the null character at the end). Failing to make the variable long enough will have unpredictable results. • To make scanf safer, use the conversion specification %ns, where n specifies the maximum number of characters to be read. Use fgets instead of gets for greater safety.

Accessing the Characters in a String • Because of the close relationship between arrays

Accessing the Characters in a String • Because of the close relationship between arrays and pointers, strings can be accessed either by array subscripting or by pointer reference. • Array version of a function that counts the number of spaces in a string: int count_spaces(const char s[]) { int count, i; count = 0; for (i = 0; s[i] != ''; i++) if (s[i] == ' ') count++; return count; }

Accessing the Characters in a String • Pointer version of the same function: int

Accessing the Characters in a String • Pointer version of the same function: int count_spaces(const char *s) { int count; count = 0; for (; *s != ''; s++) if (*s == ' ') count++; return count; }

Using the C String Library • C provides little built-in support for strings. Since

Using the C String Library • C provides little built-in support for strings. Since strings are treated as arrays, they are restricted in the same ways as arrays—in particular, strings cannot be copied or compared. • Warning: Attempts to copy or compare two strings using C’s built-in operators will fail: char str 1[10], str 2[10]; str 1 = str 2; /* illegal */ if (str 1 == str 2). . . /* will produce the wrong result */ • The C library provides a rich set of functions for performing operations on strings. Declarations for these functions reside in <string. h>.

The strcpy Function • strcpy copies one string into another: char str 1[10], str

The strcpy Function • strcpy copies one string into another: char str 1[10], str 2[10]; strcpy(str 1, "abcd"); /* str 1 now contains "abcd" */ strcpy(str 2, str 1); /* str 2 now contains "abcd" */ • strcpy calls can be chained: strcpy(str 2, strcpy(str 1, "abcd")); /* both str 1 and str 2 now contain "abcd" */ • Warning: strcpy has no way to check that the second string will fit in the first one.

The strcat Function • strcat appends the contents of one string to the end

The strcat Function • strcat appends the contents of one string to the end of another: char str[10] = "abc"; strcat(str, "def"); /* str now contains "abcdef" */ • Warning: strcat has no way to check that the first string can accommodate the added characters.

The strcmp Function • strcmp compares two strings: if (strcmp(str 1, str 2) <

The strcmp Function • strcmp compares two strings: if (strcmp(str 1, str 2) < 0). . . strcmp returns a value less than, equal to, or greater than 0, depending on whether str 1 is less than, equal to, or greater than str 2. • strcmp considers str 1 to be less than str 2 if The first i characters of str 1 and str 2 match, but the (i+1)st character of str 1 is less than the (i+1)st character of str 2 (for example, "abc" is less than "acc", and "abc" is less than "bcd"), or All characters of str 1 match str 2, but str 1 is shorter than str 2 (for example, "abc" is less than "abcd")

The strlen Function • strlen returns the length of a string: int i; char

The strlen Function • strlen returns the length of a string: int i; char str[10]; i = strlen("abc"); /* i is now 3 */ i = strlen(""); /* i is now 0 */ strcpy(str, "abc"); i = strlen(str); /* i is now 3 */ • When given an array of characters as its argument, strlen does not measure the length of the array itself; instead, it returns the length of the string stored inside the array.

Writing the strlen Function • Version 1: int strlen(const char *s) { int n;

Writing the strlen Function • Version 1: int strlen(const char *s) { int n; for (n = 0; *s != ''; s++) n++; return n; } • Version 2: int strlen(const char *s) { int n = 0; for (; *s != 0; s++) n++; return n; }

Writing the strlen Function • Version 3: int strlen(const char *s) { int n

Writing the strlen Function • Version 3: int strlen(const char *s) { int n = 0; for (; *s; s++) n++; return n; } • Version 4: int strlen(const char *s) { int n = 0; while (*s++) n++; return n; }

Writing the strcat Function char *strcat(char *s 1, const char *s 2) { char

Writing the strcat Function char *strcat(char *s 1, const char *s 2) { char *p = s 1; while (*p++); --p; while (*p++ = *s 2++); return s 1; }

Enumerations • An enumeration is a collection of named integer constants. • Enumerations are

Enumerations • An enumeration is a collection of named integer constants. • Enumerations are defined in a manner similar to structures and unions: enum bool {FALSE, TRUE}; enum rank {TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE}; enum suit {CLUBS, DIAMONDS, HEARTS, SPADES}; enum EGA_colors {BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LT_GRAY, DK_GRAY, LT_BLUE, LT_GREEN, LT_CYAN, LT_RED, LT_MAGENTA, YELLOW, WHITE};

Adding a “Tag Field” to a Union • There is no way to tell

Adding a “Tag Field” to a Union • There is no way to tell which member of a union was last assigned. To retain this information, we can create a structure with two members: (1) the union itself, and (2) a “tag field” whose value indicates which member of the union was last assigned. struct { enum {INT_KIND, DOUBLE_KIND} kind; /* tag field */ union { int i; double d; } u; } s; The tag field is often an enumeration.

5. FORMATTED INPUT/OUTPUT

5. FORMATTED INPUT/OUTPUT

Console I/O • stdout, stdin: console output and input streams • puts(string): print string

Console I/O • stdout, stdin: console output and input streams • puts(string): print string to stdout • putchar(char): print character to stdout • char = getchar(): return character from stdin • string = gets(string): read line from stdin into string

The printf Function • The first argument in a call of printf is a

The printf Function • The first argument in a call of printf is a string, which may contain both ordinary characters and conversion specifications, which begin with the % symbol. • Ordinary characters are printed as they appear in the string; conversion specifications are matched one-by-one with the remaining arguments in the call of printf: int i, j; float x, y; printf("i = %d, j = %d, x = %f, y = %fn", i, j, x, y);

The printf Function • Warning: C compilers don’t check that the number of conversion

The printf Function • Warning: C compilers don’t check that the number of conversion specifications in a format string matches the number of output items: printf("%d %dn", i); /* too few items */ printf("%dn", i, j); /* too many items */ • Furthermore, there’s no check that a conversion specification is appropriate for the type of item being printed: printf("%f %dn", i, x);

Conversion Specifications A conversion specification has the form %-m. p. X • m (optional)

Conversion Specifications A conversion specification has the form %-m. p. X • m (optional) specifies the minimum field width. • - (optional) indicates left justification within the field; the default is right justification. • . p (optional) specifies: – Number of digits after the decimal point (for a floating point number) – Minimum number of digits to print (for an integer)

Conversion Specifications • X is one of the following letters: d e f g

Conversion Specifications • X is one of the following letters: d e f g - decimal signed integer - exponential floating point - fixed decimal floating point - whichever of e or f produces a shorter string • This is not a complete description of conversion specifications.

printf Example • Sample program: #include <stdio. h> int main(void) { int i; float

printf Example • Sample program: #include <stdio. h> int main(void) { int i; float f; i = 40; f = 839. 21; printf("|%d|%5 d|%-5 d|%5. 3 d|n", i, i); printf("|%10. 3 f|%10. 3 e|%-10 g|n", f, f, f); return 0; } • Output: |40| 40|40 | 040| | 839. 210| 8. 392 e+02|839. 21 |

Escape Sequences String literals sometimes need to contain control characters (such as tab and

Escape Sequences String literals sometimes need to contain control characters (such as tab and newline) or characters that have a special meaning in C (such as "). These characters can be represented by escape sequences. Character escapes consist of followed by one character: alert (bell) a backslash \ backspace b question mark ? form feed f single quote ' new-line n double quote " carriage return r horizontal tab t vertical tab v

Escape Sequences • Writing the a escape causes a beep. • Writing the n

Escape Sequences • Writing the a escape causes a beep. • Writing the n escape causes the cursor to move to the beginning of the next line. • Writing the t escape causes the cursor to move to the next tab stop. • The " escape allows us to print the double quote character: printf(""Hello!""); • String literals may contain any number of escape sequences: printf("Itemt. Unitt. Purchasent. Pricet. Daten");

The scanf Function • scanf requires a format string, followed by variables into which

The scanf Function • scanf requires a format string, followed by variables into which input is to be stored. In most cases, each variable must be preceded by the symbol &. • Warning: Forgetting to put the & symbol in front of a variable will have unpredictable — and possibly disastrous — results.

The scanf Function • scanf format strings are similar to printf format strings, but

The scanf Function • scanf format strings are similar to printf format strings, but usually contain only conversion specifications: int i, j; float x, y; scanf("%d%d%f%f", &i, &j, &x, &y); • Note: When used with scanf, the e, f, and g conversions are identical: each causes scanf to read a floating-point number. A sign, exponent, and decimal point may or may not be present.

How scanf Works scanf ignores white-space characters (blanks, tabs, and new-line characters) when searching

How scanf Works scanf ignores white-space characters (blanks, tabs, and new-line characters) when searching for an input item. If scanf is used in the following way: scanf("%d%d%f%f", &i, &j, &x, &y); the input could be split over several lines: 1 -20. 3 -4. 0 e 3 or put on a single line: 1 -20. 3 -4. 0 e 3

How scanf Works • When scanf encounters a character that can’t be part of

How scanf Works • When scanf encounters a character that can’t be part of the current item, this character is read again during the scanning of the next input item or during the next call of scanf. Using the same call of scanf as above: scanf("%d%d%f%f", &i, &j, &x, &y); If the input is 1 -20. 3 -4. 0 e 3 z Then i is assigned the value 1, j is – 20, x is. 3, and y is – 4. 0 e 3.

The scanf Format String • A scanf format string may contain ordinary characters in

The scanf Format String • A scanf format string may contain ordinary characters in addition to conversion specifications. • A non-white-space character in a format string must match the next input character or scanf terminates without reading further. (The non-matching character can be read by a later call of scanf. ) The call scanf("%d/%d/%d", &month, &day, &year); will read 5/ 28/ 2002 but not 5 / 28 / 2002

The scanf Format String • A white-space character in a format string matches zero

The scanf Format String • A white-space character in a format string matches zero or more white-space characters in the input. The call scanf("%d /%d", &month, &day, &year); will read 5 / 28 / 2002 and all similar inputs, regardless of the amount of space before and after each / symbol.

The scanf Format String Warning: Putting a new-line character at the end of a

The scanf Format String Warning: Putting a new-line character at the end of a scanf format string is usually a bad idea: scanf("%dn", &i); • After reading an integer, scanf skips white-space characters until it finds a non-white-space character. An interactive program will hang until the user enters a nonblank character.

FILE INPUT/OUTPUT

FILE INPUT/OUTPUT

File Pointers and Streams • Declarations of functions that perform file I/O appear in

File Pointers and Streams • Declarations of functions that perform file I/O appear in <stdio. h>. Each function requires a file pointer as a parameter. • A file pointer is a pointer to a FILE structure (FILE is defined in <stdio. h>). A program may declare as many file pointers as needed: FILE *fp 1, *fp 2; • A file pointer represents a stream, which may be a file or —in general—any source of input or output.

File Pointers and Streams • Three streams are standard: stdin Standard input stdout Standard

File Pointers and Streams • Three streams are standard: stdin Standard input stdout Standard output stderr Standard error These streams need not be opened or closed. • Standard input and output can be redirected in both UNIX and Windows: prog <data >result • UNIX also allows redirection of the standard error stream. Only certain versions of Windows (NT and 2000) allow this. Redirection of standard error is done by using 2> instead of >.

Opening and Closing Files • Files can be opened by calling fopen: FILE *fopen(const

Opening and Closing Files • Files can be opened by calling fopen: FILE *fopen(const char *filename, const char *mode); mode can be one of the following: "r" Open for reading "w" Open for writing (file need not exist) "a" Open for appending (file need not exist) "r+" Open for reading and writing, starting at beginning "w+" Open for reading and writing (truncate if file exists) "a+" Open for reading and writing (append if file exists) If the file cannot be opened, fopen returns NULL. • Files can be closed by calling fclose: int fclose(FILE *stream);

Opening and Closing Files • Example: #include <stdio. h> #include <stdlib. h> #define INPUT_FILE

Opening and Closing Files • Example: #include <stdio. h> #include <stdlib. h> #define INPUT_FILE "example. dat" int main(void) { FILE *fp; fp = fopen(INPUT_FILE, "r"); if (fp == NULL) { printf("Can't open %sn", INPUT_FILE); exit(EXIT_FAILURE); } … fclose(fp); return 0; }

Command-Line Arguments • The main function may have parameters named argc and argv, which

Command-Line Arguments • The main function may have parameters named argc and argv, which allow access to the command line when the program is executed: int main(int argc, char *argv[]) { … } • argc is a count of the number of command line arguments (including the name of the program itself). • argv is an array of pointers to the command line arguments. argv[0] contains a pointer to the name of the program. argv[1] through argv[argc-1] point to the remaining command line arguments.

Command-Line Arguments • The following program (exist. c) obtains a file name from the

Command-Line Arguments • The following program (exist. c) obtains a file name from the command line and checks whether the file can be opened: #include <stdio. h> #include <stdlib. h> int main(int argc, char *argv[]) { FILE *fp; if (argc != 2) { printf("usage: exist filenamen"); exit(EXIT_FAILURE); } if ((fp = fopen(argv[1], "r")) == NULL) printf("%s does not existn", argv[1]); else { printf("%s existsn", argv[1]); fclose(fp); } return 0; }

Text I/O • The standard I/O library provides a number of functions and macros

Text I/O • The standard I/O library provides a number of functions and macros for reading character data. Here is a partial list: getc(fp) Reads a character from fp (macro) getchar() Reads a character from stdin (macro) fgetc(fp) Similar to getc, but is a function scanf(format, . . . ) Reads formatted input from stdin fscanf(fp, format, . . . ) Reads formatted input from fp gets(s) Reads characters from stdin up to next newline fgets(s, n, fp) Reads at most n – 1 characters from fp

Text I/O • Here is a partial list of output functions: putc(c, fp) Writes

Text I/O • Here is a partial list of output functions: putc(c, fp) Writes the character c to fp (macro) putchar(c) Writes the character c to stdout (macro) fputc(c, fp) Similar to putc, but is a function printf(format, . . . ) Writes formatted output to stdout fprintf(fp, format, . . . ) Writes formatted output to fp puts(s) Writes the string s to stdout fputs(s, fp) Writes the string s to fp

Text I/O • Watch out for small differences between similar functions: puts always adds

Text I/O • Watch out for small differences between similar functions: puts always adds a new-line character to the end of its output; fputs doesn’t. fgets always includes a new-line character at the end of its input string; gets doesn’t. • All output functions return a value: putc, putchar, and fputc return the character written. printf and fprintf return the number of bytes written. puts and fputs return the last character written. All seven functions return EOF (a macro defined in <stdio. h>) if an error occurs during output.

Detecting End-of-File • When getc, getchar, or fgetc detects that the end of the

Detecting End-of-File • When getc, getchar, or fgetc detects that the end of the input file has been reached or that an input error has occurred, it returns EOF. Note: All three return an integer, not a character. • The feof function can confirm that end-of-file was actually reached: int feof(FILE *stream); /* returns nonzero if eof */ • The ferror function can confirm that an error occurred: int ferror(FILE *stream); /* returns nonzero if error */

Detecting End-of-File • The value returned by scanf and fscanf indicates the actual number

Detecting End-of-File • The value returned by scanf and fscanf indicates the actual number of input items that were read. If end-of-file occurred before even one item could be read, the return value is EOF. • gets and fgets return a pointer to the string read; on error or end-of-file, they return NULL.

Binary Streams • There are two kinds of streams: A text stream consists of

Binary Streams • There are two kinds of streams: A text stream consists of lines of characters terminated by the newline character. A binary stream consists of a sequence of bytes (characters). • Under Windows, there are two differences between text streams and binary streams: When a new-line character is written to a text stream, it is expanded into a carriage- return/line-feed pair. The reverse translation takes place during input. A control-Z character (x 1 a) in an input file is assumed to mark the end of the file.

Binary Streams • Under UNIX, there is no difference between a text stream and

Binary Streams • Under UNIX, there is no difference between a text stream and a binary stream. • Whether a file is treated as a text file or a binary file depends on the mode that was specified when it was opened. The modes listed previously are used for text files. When a binary file is opened, the mode string should include the letter b: "rb" Open for reading "wb" Open for writing (file need not exist) "ab" Open for appending (file need not exist) "rb+" Open for reading and writing, starting at beginning "wb+" Open for reading and writing (truncate if file exists) "ab+" Open for reading and writing (append if file exists)

Binary I/O • The fwrite function writes a block of binary data: size_t fwrite(const

Binary I/O • The fwrite function writes a block of binary data: size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); fwrites nmemb elements of size to stream. fwrite returns the actual number of elements written. • The fread function reads a block of binary data: size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); freads up to nmemb elements of size from stream, storing them at the address specified by ptr. fread returns the actual number of elements read.

Binary I/O (Example) • #include <stdio. h> #include <string. h> int main() { FILE

Binary I/O (Example) • #include <stdio. h> #include <string. h> int main() { FILE *fp; char c[] = "this is tutorialspoint"; char buffer[100]; /* Open file for both reading and writing */ fp = fopen("file. txt", "w+"); /* Write data to the file */ fwrite(c, strlen(c) + 1, 1, fp); /* Seek to the beginning of the file */ fseek(fp, SEEK_SET, 0); /* Read and display data */ fread(buffer, strlen(c)+1, 1, fp); printf("%sn", buffer); fclose(fp); return(0); }

Binary I/O • Numeric data written using printf is converted to character form. Numeric

Binary I/O • Numeric data written using printf is converted to character form. Numeric data written using fwrite is left in binary form. Advantages of using fwrite: Less disk space is required. Writing and reading takes less time. Disadvantages: Data can’t be read easily by humans. Data isn’t portable between different types of computers. • Although fread and fwrite are normally applied to binary streams, they can be used with text streams as well. Conversely, the text I/O functions can be used with binary streams. In both cases, however, watch out for unexpected results.

Random Access • The fseek, ftell, and rewind functions support random access within files.

Random Access • The fseek, ftell, and rewind functions support random access within files. Random access is most often used with binary files. These functions can also be used with text files, but some restrictions apply. • fseek allows repositioning within a file. int fseek(FILE *stream, long int offset, int whence); The new file position is determined by offset and whence. offset is a (possibly negative) byte count relative to the position specified by whence must have one of the following values: SEEK_SET Beginning of file SEEK_CUR Current file position SEEK_END End of file

Random Access • Examples of fseek: fseek(fp, 0, SEEK_SET); /* move to beginning of

Random Access • Examples of fseek: fseek(fp, 0, SEEK_SET); /* move to beginning of file */ fseek(fp, 0, SEEK_END); /* move to end of file */ fseek(fp, -10, SEEK_CUR); /* move back 10 bytes */ • ftell returns the current file position: long int ftell(FILE *stream); This may be saved and later supplied to a call of fseek: long int file_pos; file_pos = ftell(fp); … fseek(fp, file_pos, SEEK_SET); /* return to previous position */ • The call rewind(fp) is equivalent to fseek(fp, 0, SEEK_SET).

Random Access (Example) #include <stdio. h> int main () { FILE *fp; fp =

Random Access (Example) #include <stdio. h> int main () { FILE *fp; fp = fopen("file. txt", "w+"); fputs("This is tutorialspoint. com", fp); fseek( fp, 7, SEEK_SET ); fputs(" C Programming Language", fp); fclose(fp); return(0); } Result: This is C Programming Language

Example Program: Modifying a Database #include <stdio. h> #include <stdlib. h> #define NAME_LEN 25

Example Program: Modifying a Database #include <stdio. h> #include <stdlib. h> #define NAME_LEN 25 #define MAX_PARTS 100 #define DATA_FILE "invent. dat" struct part { int part_no; char part_name[NAME_LEN+1]; int on_hand; } inventory[MAX_PARTS]; int num_parts;

Example Program: Modifying a Database int main(void) { FILE *fp = fopen(DATA_FILE, "rb+"); if

Example Program: Modifying a Database int main(void) { FILE *fp = fopen(DATA_FILE, "rb+"); if (fp == NULL) { fprintf(stderr, "Can't open %sn", DATA_FILE); exit(EXIT_FAILURE); } num_parts = fread(inventory, sizeof(struct part), MAX_PARTS, fp); /* modify inventory */ rewind(fp); fwrite(inventory, sizeof(struct part), num_parts, fp); fclose(fp); return 0; }

(3) Control Flow

(3) Control Flow

if Statements The if statement has two forms: if ( expression ) statement else

if Statements The if statement has two forms: if ( expression ) statement else statement If the value of the expression is nonzero, the first statement is executed; if the value is zero, the second statement (if present) is executed.

if Statements Examples: if (i > j) max = i; else max = j;

if Statements Examples: if (i > j) max = i; else max = j; if (i > j) if (i > k) else max = else if (j > k) else max = /* max becomes the */ /* larger of I and j */ max = i; k; max = j; k; /* max becomes */ /* largest of */ /* i, j, k */

if Statements Examples: if (i < 0) printf("Less than zero"); else if (i ==

if Statements Examples: if (i < 0) printf("Less than zero"); else if (i == 0) printf("Equal to zero"); else printf("Greater than zero"); Warning: Don’t confuse = (assignment) with == (equality): if (i = 0). . . /* assigns i the value 0 */ if (i == 0). . . /* tests whether i is equal to 0 */

Compound Statements A compound statement has the form { statements } Compound statements are

Compound Statements A compound statement has the form { statements } Compound statements are used whenever C requires a single statement, but we want to include more than one statement. Compound statements, unlike ordinary statements, are not followed by a semicolon. Example: if (i < j) { temp = i; i = j; j = temp; } /* this swaps i and j */

The “Dangling else” Problem • Warning: Watch out for the “dangling else” problem: if

The “Dangling else” Problem • Warning: Watch out for the “dangling else” problem: if (y != 0) if (x != 0) result = x / y; else printf("Error: y is equal to 0n"); • Use the compound statement to fix it: if (y != 0) { if (x != 0) result = x / y; } else printf("Error: y is equal to 0n");

switch Statements • The switch statement allows a program to perform one of several

switch Statements • The switch statement allows a program to perform one of several actions, depending on the value of an expression. • Example: int grade; . . . switch (grade) { case 4: printf("Excellent"); break; case 3: printf("Good"); break; case 2: printf("Average"); break; case 1: printf("Poor"); break; case 0: printf("Failing"); break; default: printf("Illegal grade"); }

switch Statements • The switch statement has the form switch ( expression ) {

switch Statements • The switch statement has the form switch ( expression ) { case constant-expression : statements … case constant-expression : statements default : statements } • Only integers and characters may be tested in a switch statement.

switch Statements • Each occurrence of the word case must be followed by a

switch Statements • Each occurrence of the word case must be followed by a single constant expression; however, several case prefixes may be combined: switch (grade) { case 4: case 3: case 2: case 1: printf("Passing"); break; case 0: printf("Failing"); break; default: printf("Illegal grade"); }

switch Statements Normally, the last statement in each case is break, but this is

switch Statements Normally, the last statement in each case is break, but this is not required. Warning: Forgetting to include break is a common error: switch (grade) { case 4: case 3: case 2: case 1: printf("Passing"); /* error */ case 0: printf("Failing"); break; default: printf("Illegal grade"); }

switch Statements • The default clause is not required: switch (grade) { case 4:

switch Statements • The default clause is not required: switch (grade) { case 4: printf("Excellent"); break; case 3: printf("Good"); break; case 2: printf("Average"); break; case 1: printf("Poor"); break; case 0: printf("Failing"); break; } • If the value of the switch expression does not match any of the case labels, control passes to the next statement.

while Statements • The while statement has the form while ( expression ) statement

while Statements • The while statement has the form while ( expression ) statement • The body of a while statement is executed repeatedly as long as the expression is true (has a nonzero value). The expression is tested before each execution of the body. • Example: i = 10; while (i > 0) { printf("T minus %d and countingn", i); --i; }

while Statements • An alternative: i = 10; while (i) printf("T minus %d and

while Statements • An alternative: i = 10; while (i) printf("T minus %d and countingn", i--); • Using a nonzero constant as the controlling expression creates an infinite loop: while (1) {. . . }

Example: Summing a Series of Numbers #include <stdio. h> int main(void) { int n,

Example: Summing a Series of Numbers #include <stdio. h> int main(void) { int n, sum = 0; printf("This program sums a series of numbers. n"); printf("Enter numbers (0 to terminate): "); scanf("%d", &n); while (n != 0) { sum += n; scanf("%d", &n); } printf("The sum is: %dn", sum); return 0; }

do Statements • The do statement has the form do statement while ( expression

do Statements • The do statement has the form do statement while ( expression ) ; • The do statement is the same as the while statement, except that the expression is evaluated after each execution of the loop. • Example: i = 10; do { printf("T minus %d and countingn", i); --i; } while (i > 0);

for Statements • The for statement has the form for ( expr 1 ;

for Statements • The for statement has the form for ( expr 1 ; expr 2 ; expr 3 ) statement • The following code expresses the meaning of the for statement: expr 1; while (expr 2) { statement expr 3; } /* exception: */ /* continue statement */ /* (later) */

for Statements • For example, the statement for (i = 10; i > 0;

for Statements • For example, the statement for (i = 10; i > 0; --i) printf("T minus %d and countingn", i); is equivalent to i = 10; while (i > 0) { printf("T minus %d and countingn", i); --i; }

for Statements • Any or all of the three expressions in a for statement

for Statements • Any or all of the three expressions in a for statement may be omitted: i = 10; for (; i > 0; --i) printf("T minus %d and countingn", i); for (i = 10; i > 0; ) printf("T minus %d and countingn", i--); i = 10; for (; i > 0; ) printf("T minus %d and countingn", i--);

for Statements • Omitting the middle expression creates an infinite loop. The statement for

for Statements • Omitting the middle expression creates an infinite loop. The statement for (; ; ) {. . . } is equivalent to while (1) {. . . }

Comma Operator The for statement is normally controlled by three expressions. The comma operator

Comma Operator The for statement is normally controlled by three expressions. The comma operator allows us to have more than three: for (sum = 0, i = 1; i <= N; i++) sum += i; In general, a comma expression has the form expr 1 , expr 2 expr 1 is first evaluated and its value discarded; the value of expr 2 is the value of the entire expression. The comma operator is handy whenever C requires a single expression, but we’d like to have two or more expressions. In practice, it appears primarily in for statements and macros.

General Rules for Loops When designing a loop, try to use a for statement

General Rules for Loops When designing a loop, try to use a for statement instead of a while or do statement, especially if the loop “counts up” or “counts down. ” Become familiar with the patterns that most often appear in for statements: Counting up from 0 to N– 1: for (i = 0; i < N; i++). . . Counting up from 1 to N: for (i = 1; i <= N; i++). . . Counting down from N– 1 to 0: for (i = N-1; i >= 0; i--). . . Counting down from N to 1: for (i = N; i > 0; i--). . .

General Rules for Loops If a for statement would be awkward, use a while

General Rules for Loops If a for statement would be awkward, use a while statement instead. Use a do statement instead of a while statement if the controlling condition must be tested after the loop body has been executed.

break Statement Can be used to jump out of a while, do, for, or

break Statement Can be used to jump out of a while, do, for, or switch statement. Example: sum = 0; while (1) { printf("Enter a number: "); scanf("%d", &i); if (i == 0) break; sum += i; }

continue Statement Can appear in while, do, and for statements. Causes the program to

continue Statement Can appear in while, do, and for statements. Causes the program to skip the rest of the current loop iteration. Example: n = 0; sum = 0; do { scanf("%d", &i); /* read (and sum) if (i == 0) continue; /* ten numbers, ++n; sum += i; } while (n < 10); */ */ /* skipping zeroes */

Null Statement The null statement is just a semicolon: i = 0; ; j

Null Statement The null statement is just a semicolon: i = 0; ; j = 1; The null statement is primarily good for one thing: writing loops whose bodies are empty. For example, the statement for (div = 2; div < n; div++) if (n % div == 0) break; can be rewritten as a loop with an empty body: for (div = 2; div < n && n % div != 0; div++);

Null Statement Warning: Accidentally putting a semicolon after the parentheses in an if, while,

Null Statement Warning: Accidentally putting a semicolon after the parentheses in an if, while, or for statement will not be detected by the compiler. if (i < 0); /* error */ printf("Error: i is less than zeron"); i = 10; while (i > 0); /* error */ { printf("T minus %d and countingn", i); --i; } for (i = 10; i > 0; --i); /* error */ printf("T minus %d and countingn", i);

Examples Average numbers until 0 is entered Sum odd and even numbers between m

Examples Average numbers until 0 is entered Sum odd and even numbers between m and n Probability of two people with the same birthday Easier to calculate the probability of no one with the same birthday Calculate factorial Print multiplication table for numbers 1 to N