├── 10 ├── 10.1.3.scope.c ├── 10.1.global-stack.c ├── 10.2-5.poker.c ├── 10.6.single-digit-RPN-calculator.c ├── 10.7.seven-segment-dynamic-buffer.c ├── 10.7.seven-segment-no-buffer.c └── 10.7.seven-segment-static-buffer.c ├── 11 ├── 11.1.currency-denominations.c ├── 11.2.find-departure.c ├── 11.4.4.swap.c ├── 11.4.5.split_time.c ├── 11.4.6.two_largest.c ├── 11.4.7.split_date.c ├── 11.4.poker.c └── 11.5.8.pointer_to_largest.c ├── 12 ├── 12.1.2.low-middle-high.c ├── 12.1.reverse.c ├── 12.2.3.reverse.c ├── 12.2.4.stack_functions.c ├── 12.2.palindrome.c ├── 12.3.10.find-middle.c ├── 12.3.11.find-largest.c ├── 12.3.12.two-largest.c ├── 12.3.6.refactor-to-pointer-arithmetic.c ├── 12.3.7.search.c ├── 12.3.8.clear.c ├── 12.3.9.inner-product.c ├── 12.4.13.identity-matrix.c ├── 12.4.17.sum-2-dimensional-array.c ├── 12.4.18.evaluate-chess-position.c ├── 12.5.reverse-sentence.c ├── 12.6.qsort.c └── 12.7-maxmin.c ├── 13 ├── 13.1-smallest-largest.c ├── 13.10-reverse-name.c ├── 13.11-average-word-length.c ├── 13.12-reverse-sentence.c ├── 13.13-ceasar-cipher.c ├── 13.15-RPN-calculator.c ├── 13.2-remind.c ├── 13.3-deal.c ├── 13.3.1-single-newline.c ├── 13.3.2-pointer-to-string.c ├── 13.3.3-scanf.c ├── 13.3.4-read-line-no-whitespace.c ├── 13.3.4-read-line-truncate.c ├── 13.3.4-read-line-with-newline.c ├── 13.3.4-read-line.c ├── 13.4-reverse.c ├── 13.4.5-capitalize.c ├── 13.4.6-censor.c ├── 13.5-sum.c ├── 13.5.11-str-cmp.c ├── 13.5.12-get-extension.c ├── 13.5.13-index-url.c ├── 13.6-planet.c ├── 13.6.16-count-spaces.c ├── 13.6.17-test-extension.c ├── 13.6.18-remove-filename.c ├── 13.7-spell-number.c ├── 13.8-scrabble.c └── 13.9-vowel-count.c ├── 14 └── 14.3.c ├── 15 ├── 15.1.justify.c ├── 15.3.qsort.c ├── 15.5.RPN-calculator.c ├── makefile ├── quicksort.c ├── quicksort.h ├── stack.c └── stack.h ├── 16 ├── 16.1.4.type-complex.c ├── 16.1.5-6.c ├── 16.1.7.fraction.c ├── 16.1.9.color.c ├── 16.1.country-codes.c ├── 16.1.exercises.c ├── 16.5.20.directions.c ├── 16.inventory.c └── makefile ├── 17 ├── 17.1.1-malloc-or-die.c ├── 17.2.2-duplicate.c ├── 17.3-inventory.c ├── 17.3.3-create-array.c ├── 17.4-line.c ├── 17.5-list-exercises.c ├── 17.5-sort-words.c ├── 17.5.13-bad-insert.lst ├── 17.5.4-dynamic-rectangle.c ├── 17.5.8-stack.c ├── 17.7-vstring-reminders.c └── makefile ├── 18 └── 18.2.h ├── 19 ├── 19.1-nester-tester.c ├── 19.2-RPN-calculator.c ├── 19.3a.bounded-queue.c ├── 19.5-queue-client.c └── makefile ├── 20 ├── 20.1-exercises.c └── swap_bytes.c ├── 21 └── 21.1-offsetof.c ├── 22 ├── 22.1-readable.c ├── 22.11-format-dates.c ├── 22.13-find-departure.c ├── 22.14-ceasar-cipher.c ├── 22.15-justify.c ├── 22.16-cp.c ├── 22.17-format-phone.c ├── 22.19-convert-line-endings.c ├── 22.2-fupcase.c ├── 22.2.3-fopen.c ├── 22.3-cat.c ├── 22.3-formatted-io.c ├── 22.3.7-file-position.c ├── 22.3.8-parser.c ├── 22.4-character-io.c ├── 22.4-wc.c ├── 22.5-line-io.c ├── 22.5-xor.c ├── 22.6-xxd.c ├── 22.7-rle.c ├── 22.9-merge-parts.c ├── generate-parts.c ├── makefile ├── parts-io-profile.log └── parts-io-profiler.c ├── 23 └── 23.8-numchar.c ├── 25 └── 25.2-print-lconv.c ├── .gitignore ├── 02 ├── currency-denominations.c ├── display-tax.c ├── loan-balance.c ├── polynomial.c └── volume_of_sphere.c ├── 03 ├── 3.1.2.float_format.c ├── 3.2.4.scanf_input.c ├── addfrac.c ├── flip-date-fields.c ├── magic-square.c ├── parse-ISBN.c ├── product-table.c └── telephone-number.c ├── 05 ├── 5.1.4-3-possiblities.c ├── 5.2.8-refactor-out-complexity.c ├── beaufort-scale.c ├── broker.c ├── digit-counter.c └── time-converter.c ├── 08 ├── 8.1.initializers.c ├── 8.10.find-departure.c ├── 8.11.xlat-phone.c ├── 8.12.scrabble.c ├── 8.13.names.c ├── 8.14.reverse-sentence.c ├── 8.15.ceasar-cipher.c ├── 8.16.anagram-test.c ├── 8.17.magic-square.c ├── 8.2.6-seven-segment.c ├── 8.6.jerk-filter.c ├── 8.7-matrix.c ├── 8.8-quiz-stats.c ├── 8.9.table-walk.c ├── interest.c ├── repdigit.c └── reverse.c ├── 09 ├── 9.1.function_exercises.c ├── 9.1.select-sort.c ├── 9.3.10.array_value_functions.c ├── 9.3.11.gpa.c ├── 9.3.table-walk.c ├── 9.4.anagram-test.c ├── 9.5.magic-square.c └── 9.8.craps.c ├── Makefile ├── Readme.md ├── data ├── 100k-parts.dat ├── 21-parts.dat ├── adjectives.txt ├── consecutive-newlines.txt ├── empty.txt ├── flights.txt ├── has-blanks.txt ├── no-newline.txt ├── nouns.txt ├── one-liner.txt ├── one-part.dat ├── runs.txt ├── two-parts.dat ├── us-phone-numbers.txt └── windows.txt ├── include ├── bounded-queue.h ├── chess.h ├── error.h ├── find-departure.h ├── global-queue.h ├── inventory-view.h ├── line.h ├── part-type.h ├── part.h ├── parts.h ├── queue.h ├── readline.h ├── rectangle.h ├── run-length-encoding.h ├── test_runner.h ├── time_helper.h ├── tokenize.h └── word.h ├── lib ├── bounded-queue.c ├── chess.c ├── error.c ├── find-departure-unbuffered.c ├── find-departure.c ├── global-queue.c ├── inventory-view.c ├── line.c ├── makefile ├── part-structs-array.c ├── part.c ├── parts-array.c ├── parts-list.c ├── parts.c ├── queue.c ├── readline.c ├── rectangle.c ├── run-length-encoding.c ├── time_helper.c ├── tokenize.c └── word.c ├── make ├── clean.mk ├── env.mk └── generic.mk ├── spec ├── bounded-queue-spec.c ├── chess-spec.c ├── global-queue-spec.c ├── makefile ├── part-spec.c ├── parts-array-resize-spec.c ├── parts-io-spec.c ├── parts-spec.c ├── queue-spec.c └── rectangle-spec.c ├── src ├── addfrac.c ├── airmiles.c ├── average.c ├── broker.c ├── canopen.c ├── celsius.c ├── checking.c ├── countdown.c ├── date.c ├── datetime.c ├── deal.c ├── dweight.c ├── dweight2.c ├── fcopy.c ├── guess.c ├── guess2.c ├── interest.c ├── invclear.c ├── inventory.c ├── inventory2.c ├── justify.c ├── length.c ├── length2.c ├── line.c ├── line.h ├── maxmin.c ├── numdigits.c ├── planet.c ├── poker.c ├── prime.c ├── pun.c ├── pun2.c ├── qsort.c ├── quadratic.c ├── readline.c ├── readline.h ├── remind.c ├── remind2.c ├── repdigit.c ├── reverse.c ├── reverse2.c ├── reverse3.c ├── square.c ├── square2.c ├── square3.c ├── stack.h ├── stack1.c ├── stack2.c ├── stackADT.c ├── stackADT.h ├── stackADT2.c ├── stackADT2.h ├── stackADT3.c ├── stackclient.c ├── sum.c ├── sum2.c ├── tabulate.c ├── tcasemap.c ├── tclassify.c ├── tnumconv.c ├── tprintf.c ├── trand.c ├── tsetjmp.c ├── tsignal.c ├── upc.c ├── viewmemory.c ├── word.c ├── word.h └── xor.c └── weird ├── compound-literal-string-parameter-clang-bug.c ├── fgets-buffer-overflow.c ├── malloc-gives-a-million-for-request-of-10.c ├── scanf-clobbers-adjacent-var.c └── scanf-clobbers-adjacent-var.gdb.log /02/currency-denominations.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int amount, remainder, twenties, tens, fives, ones; 6 | 7 | printf("Enter a dollar amount: "); 8 | scanf("%d", &amount); 9 | 10 | twenties = amount / 20; 11 | remainder = amount % 20; 12 | tens = remainder / 10; 13 | remainder = remainder % 10; 14 | fives = remainder / 5; 15 | remainder = remainder % 5; 16 | ones = remainder; 17 | 18 | printf("$20 bills: %d\n", twenties); 19 | printf("$10 bills: %d\n", tens); 20 | printf("$5 bills: %d\n", fives); 21 | printf("$1 bills: %d\n", ones); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /02/display-tax.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | float amount, tax; 6 | 7 | printf("Enter a dollar amount: "); 8 | scanf("%f", &amount); 9 | 10 | tax = amount * 0.05f; 11 | 12 | printf("With tax added: $%.2f\n", amount + tax); 13 | 14 | /*nicer solution from KNKing (1 less variable)*/ 15 | /*printf("With tax added: $%.2f\n", amount * 1.05f);*/ 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /02/loan-balance.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | 6 | float balance, rate, monthly_rate, interest, payment; 7 | 8 | printf("Enter amount of loan: "); 9 | scanf("%f", &balance); 10 | printf("Enter interest rate: "); 11 | scanf("%f", &rate); 12 | printf("Enter monthly payment: "); 13 | scanf("%f", &payment); 14 | 15 | monthly_rate = (rate * 0.01f) / 12.0; 16 | 17 | interest = balance * monthly_rate; 18 | balance += interest; 19 | balance = balance - payment; 20 | 21 | printf("Balance after payment 1: $%.2f\n", balance); 22 | 23 | interest = balance * monthly_rate; 24 | balance += interest; 25 | balance = balance - payment; 26 | 27 | printf("Balance after payment 2: $%.2f\n", balance); 28 | 29 | interest = balance * monthly_rate; 30 | balance += interest; 31 | balance = balance - payment; 32 | 33 | printf("Balance after payment 3: $%.2f\n", balance); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /02/polynomial.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int x, tmp; 6 | int horners_result; 7 | int cf1, cf2, cf3, cf4, cf5, cf6; /* coefficients */ 8 | 9 | printf("3x^5 + 2x^4 - 5x^3 - x^2 + x7 - 6\n"); 10 | printf("Enter a value for x: "); 11 | scanf("%d", &x); 12 | 13 | tmp = 3 * x; 14 | cf1 = tmp * tmp * tmp * tmp * tmp; 15 | tmp = 2 * x; 16 | cf2 = tmp * tmp * tmp * tmp; 17 | tmp = 5 * x; 18 | cf3 = tmp * tmp * tmp; 19 | cf4 = x * x; 20 | cf5 = 7 * x; 21 | cf6 = 6; 22 | 23 | printf("result: %d\n", cf1 + cf2 - cf3 - cf4 + cf5 - cf6); 24 | printf("Horner's rule: ((((3x + 2)x - 5)x - 1)x + 7)x - 6\n"); 25 | 26 | /*Not sure where the mistake is, but the 2 algorithms (above, and the Horner's rule version below) produce different results*/ 27 | 28 | /*Both versions below give the same result:*/ 29 | /* 30 | horners_result = ( 31 | ( ( 32 | ( ( 33 | ( ( 34 | ( (3 * x) + 2) * x 35 | ) - 5) * x 36 | ) - 1) * x 37 | ) + 7) * x 38 | ) - 6; 39 | */ 40 | 41 | horners_result = (((((3 * x) + 2) * x - 5) * x - 1) * x + 7) * x - 6; 42 | 43 | printf("result: %d\n", horners_result); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /02/volume_of_sphere.c: -------------------------------------------------------------------------------- 1 | #include 2 | # define M_PI 3.14159265358979323846 /* pi */ 3 | 4 | int main(void) 5 | { 6 | float volume, radius; 7 | 8 | printf("Enter a radius: "); 9 | scanf("%f", &radius); 10 | 11 | volume = 4.0f/3.0f * M_PI * radius; 12 | 13 | printf("Volume of Sphere (radius %.2f): %.10f\n", radius, volume); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /03/3.1.2.float_format.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("Exercise 3.1.1\n"); 6 | printf("%6d, %4d\n", 86, 1040); 7 | printf("%12.5e\n", 30.253); 8 | printf("%.4f\n", 83.162); 9 | printf("%-6.2g\n", .0000009979); 10 | 11 | 12 | printf("\nExercise 3.1.2\n"); 13 | 14 | float x = 12.9f; 15 | printf("|%-8.1e|%10.6e|%-8.3f|%6.0f|\n", x, x, x, x); 16 | 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /03/3.2.4.scanf_input.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | 6 | int i, j; 7 | float x; 8 | 9 | scanf("%d%f%d", &i, &x, &j); 10 | 11 | printf("i: %d\nx: %.2f\nj: %d\n", i, x, j); 12 | return 0; 13 | 14 | /* 15 | * I was right! Since "." can't be part of an int, 16 | * processing of int i stops at the dot, and processing of float x 17 | * STARTS at the dot. 18 | * 19 | tim@fern:~/c/c-programming$ 03/3.2.4.scanf_input 20 | 10.3 5 6 21 | i: 10 22 | x: 0.30 23 | j: 5 24 | */ 25 | } 26 | -------------------------------------------------------------------------------- /03/addfrac.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int num1, num2, denom1, denom2, result_num, result_denom; 6 | 7 | printf("Enter two fractions separated by a plus sign: "); 8 | scanf("%d / %d + %d / %d", &num1, &denom1, &num2, &denom2); 9 | 10 | result_num = num1 * denom2 + num2 * denom1; 11 | result_denom = denom1 * denom2; 12 | 13 | printf("The sum is %d/%d\n", result_num, result_denom); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /03/flip-date-fields.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int mm, dd, yyyy; 6 | 7 | printf("Enter a date (mm/dd/yyyy): "); 8 | scanf("%d/%d/%d", &mm, &dd, &yyyy); 9 | 10 | printf("You entered the date %d%.2d%.2d\n", yyyy, mm, dd); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /03/magic-square.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int r1c1, r1c2, r1c3, r1c4; 6 | int r2c1, r2c2, r2c3, r2c4; 7 | int r3c1, r3c2, r3c3, r3c4; 8 | int r4c1, r4c2, r4c3, r4c4; 9 | 10 | char *row_format = "%2d\t%2d\t%2d\t%2d\n"; 11 | printf("Enter the numbers from 1 to 16 in any order:\n"); 12 | scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",\ 13 | &r1c1, &r1c2, &r1c3, &r1c4, \ 14 | &r2c1, &r2c2, &r2c3, &r2c4, \ 15 | &r3c1, &r3c2, &r3c3, &r3c4, \ 16 | &r4c1, &r4c2, &r4c3, &r4c4); 17 | 18 | printf(row_format, r1c1, r1c2, r1c3, r1c4); 19 | printf(row_format, r2c1, r2c2, r2c3, r2c4); 20 | printf(row_format, r3c1, r3c2, r3c3, r3c4); 21 | printf(row_format, r4c1, r4c2, r4c3, r4c4); 22 | 23 | printf("Row sums: %2d %2d %2d %2d\n", \ 24 | r1c1 + r1c2 + r1c3 + r1c4, \ 25 | r2c1 + r2c2 + r2c3 + r2c4, \ 26 | r3c1 + r3c2 + r3c3 + r3c4, \ 27 | r4c1 + r4c2 + r4c3 + r4c4); 28 | printf("Column sums: %2d %2d %2d %2d\n", \ 29 | r1c1 + r2c1 + r3c1 + r4c1, \ 30 | r1c2 + r2c2 + r3c2 + r4c2, \ 31 | r1c3 + r2c3 + r3c3 + r4c3, \ 32 | r1c4 + r2c4 + r3c4 + r4c4); 33 | 34 | printf("Diagonal sums: %2d %2d\n", \ 35 | r1c1 + r2c2 + r3c3 + r4c4, \ 36 | r4c1 + r3c2 + r2c3 + r1c4); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /03/parse-ISBN.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int gs1_prefix, group_id, publisher_code, item_number, check_digit; 6 | 7 | printf("Enter ISBN: "); 8 | scanf("%d-%d-%d-%d-%d", &gs1_prefix, &group_id, &publisher_code, &item_number, &check_digit); 9 | 10 | printf("GS1 prefix: %d\n", gs1_prefix); 11 | printf("Group Identifier: %d\n", group_id); 12 | printf("Publisher Code: %d\n", publisher_code); 13 | printf("Item Number: %d\n", item_number); 14 | printf("Check Digit: %d\n", check_digit); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /03/product-table.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | 6 | int item_number, mm, dd, yyyy; 7 | float unit_price; 8 | 9 | printf("Enter item number: "); 10 | scanf("%d", &item_number); 11 | printf("Enter unit price: "); 12 | scanf("%f", &unit_price); 13 | printf("Enter purchase date (mm/dd/yyyy): "); 14 | scanf("%d/%d/%d", &mm, &dd, &yyyy); 15 | 16 | printf("\n"); 17 | printf("Item\t\t\tUnit\t\t\tPurchase\n"); 18 | printf(" \t\t\tPrice\t\t\tDate\n"); 19 | printf("%-d\t\t\t$%4.2f\t\t\t%.2d/%.2d/%4d\n", item_number, unit_price, mm, dd, yyyy); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /03/telephone-number.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int area_code, exchange, number; 6 | printf("Enter phone number [(xxx) xxx-xxxx]: "); 7 | 8 | scanf("(%d) %d-%d", &area_code, &exchange, &number); 9 | 10 | printf("You entered %3d.%3d.%4d\n", area_code, exchange, number); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /05/5.1.4-3-possiblities.c: -------------------------------------------------------------------------------- 1 | #include 2 | /*Write a single expression whose value is either -1, 0, or +1, 3 | depending on whether i is less than, equal to, or greater than j, respectively.*/ 4 | 5 | void test(int i, int j) 6 | { 7 | int result = i < j ? -1 : i > j; 8 | 9 | /*The following 2 also work*/ 10 | /*result = i < j ? -1 : ( i > j );*/ 11 | /*result = i < j ? -1 : ( i == j ? 0 : 1);*/ 12 | printf("i=%d, j=%d: %d\n", i, j, result); 13 | } 14 | 15 | int main(void) 16 | { 17 | test(1,2); 18 | test(2,2); 19 | test(2,1); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /05/5.2.8-refactor-out-complexity.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | The following if statement is unnecessarily complicated. 6 | Simplify it as much as possible. 7 | 8 | if (age >= 13) 9 | if (age <= 19) 10 | teenager = true; 11 | else 12 | teenager = false; 13 | else if (age < 13) 14 | teenager = false; 15 | */ 16 | void test(int age) 17 | { 18 | printf("Age %d: teenager? %d\n", age, (age > 12 && age < 20) ? true : false); 19 | } 20 | int main(void) 21 | { 22 | test(0); 23 | test(1); 24 | test(12); 25 | test(13); 26 | test(19); 27 | test(20); 28 | test(101); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /05/beaufort-scale.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char *description; 6 | float wind_speed; 7 | 8 | printf("Enter wind speed (knots): "); 9 | scanf("%f", &wind_speed); 10 | 11 | if (wind_speed < 1.0f) 12 | description = "Calm"; 13 | else if (wind_speed < 4.0f) 14 | description = "Light air"; 15 | else if (wind_speed < 28.0f) 16 | description = "Breeze"; 17 | else if (wind_speed < 48.0f) 18 | description = "Gale"; 19 | else if (wind_speed < 63.01f) 20 | description = "Storm"; 21 | else 22 | description = "Hurricane"; 23 | 24 | printf("Wind Force: %s\n", description); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /05/broker.c: -------------------------------------------------------------------------------- 1 | /* Calculate a broker's commission */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | int shares; 7 | float price, commission, value, percentage, base; 8 | float minimum = 39.00; 9 | 10 | printf("Number of shares: "); 11 | scanf("%d", &shares); 12 | 13 | printf("Price per share: "); 14 | scanf("%f", &price); 15 | 16 | value = price * shares; 17 | 18 | if (value < 2500.00f) { 19 | base = 30.00; 20 | percentage = .017; 21 | } else if (value < 6250.00f) { 22 | base = 56.00; 23 | percentage = .0066; 24 | } else if (value < 2000.00f) { 25 | base = 76.00; 26 | percentage = .0034; 27 | } else if (value < 50000.00f) { 28 | base = 100.00; 29 | percentage = .0022; 30 | } else if (value < 500000.00f) { 31 | base = 155.00; 32 | percentage = .0011; 33 | } else { 34 | base = 255.00; 35 | percentage = .0009; 36 | } 37 | 38 | commission = base + percentage * value; 39 | 40 | if (commission < minimum) 41 | commission = minimum; 42 | 43 | printf("Our Commission: $%.2f\n", commission); 44 | 45 | base = 33.00; 46 | percentage = 0.02; 47 | if (shares > 2000) 48 | percentage = 0.03; 49 | 50 | commission = base + shares * percentage; 51 | printf("Their Commission: $%.2f\n", commission); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /05/digit-counter.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int input, absolute_value, count; 6 | 7 | printf("Enter a number: "); 8 | scanf("%d", &input); 9 | 10 | absolute_value = input < 1 ? input * -1 : input; 11 | if (absolute_value < 10) 12 | count = 1; 13 | else if (absolute_value < 100) 14 | count = 2; 15 | else if (absolute_value < 1000) 16 | count = 3; 17 | else if (absolute_value < 10000) 18 | count = 4; 19 | printf("The number %d has %d digits\n", input, count); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /05/time-converter.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int hours, minutes; 6 | char meridian[] = "AM"; 7 | 8 | printf("Enter a 24-hour time: "); 9 | scanf("%d:%d", &hours, &minutes); 10 | 11 | if (hours >= 12) { 12 | meridian[0] = 'P'; 13 | hours -= 12; 14 | } 15 | if (hours == 0) 16 | hours = 12; 17 | 18 | printf("Equivalent 12-hour time: %d:%.2d %s\n", hours, minutes, meridian); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /08/8.1.initializers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define FIB_MAX 40 4 | int main(void) 5 | { 6 | bool weekend[] = {true, false, false, false, false, false, true}; 7 | bool wochenende[] = {[0] = true, [6] = true}; 8 | int fibonacci_sequence[40] = {0, 1}; 9 | 10 | int i; 11 | for (i = 2; i < FIB_MAX; i++) { 12 | fibonacci_sequence[i] = fibonacci_sequence[i-2] + fibonacci_sequence[i-1]; 13 | } 14 | 15 | for (i = 0; i < FIB_MAX; i++) { 16 | printf("%2d)\t%3d\n", i + 1, fibonacci_sequence[i]); 17 | } 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /08/8.11.xlat-phone.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char phone_number[15]; 7 | char ch; 8 | int i; 9 | printf("Enter phone number: "); 10 | while ((ch = getchar()) != '\n') { 11 | switch(toupper(ch)) { 12 | case 'A': 13 | case 'B': 14 | case 'C': 15 | phone_number[i] = '2'; 16 | break; 17 | case 'D': 18 | case 'E': 19 | case 'F': 20 | phone_number[i] = '3'; 21 | break; 22 | case 'G': 23 | case 'H': 24 | case 'I': 25 | phone_number[i] = '4'; 26 | break; 27 | case 'J': 28 | case 'K': 29 | case 'L': 30 | phone_number[i] = '5'; 31 | break; 32 | case 'M': 33 | case 'N': 34 | case 'O': 35 | phone_number[i] = '6'; 36 | break; 37 | case 'P': 38 | case 'Q': 39 | case 'R': 40 | case 'S': 41 | phone_number[i] = '7'; 42 | break; 43 | case 'T': 44 | case 'U': 45 | case 'V': 46 | phone_number[i] = '8'; 47 | break; 48 | case 'W': 49 | case 'X': 50 | case 'Y': 51 | case 'Z': 52 | phone_number[i] = '9'; 53 | break; 54 | default: 55 | phone_number[i] = ch; 56 | } 57 | i++; 58 | } 59 | 60 | printf("In numeric form: %s\n", phone_number); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /08/8.12.scrabble.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | int sum = 0; 7 | char ch; 8 | int scrabble_weights[26] = { 9 | 1, //A 10 | 3, //B 11 | 3, //C 12 | 2, //D 13 | 1, //E 14 | 4, //F 15 | 2, //G 16 | 4, //H 17 | 1, //I 18 | 8, //J 19 | 5, //K 20 | 1, //L 21 | 3, //M 22 | 1, //N 23 | 1, //0 24 | 3, //P 25 | 10,//Q 26 | 1, //R 27 | 1, //S 28 | 1, //T 29 | 1, //U 30 | 4, //V 31 | 4, //W 32 | 8, //X 33 | 4, //Y 34 | 10 //Z 35 | }; 36 | 37 | printf("Enter a word: "); 38 | 39 | while ((ch = getchar()) != '\n') { 40 | sum += scrabble_weights[toupper(ch) - 'A']; 41 | } 42 | 43 | printf("Scrabble Value: %d\n", sum); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /08/8.13.names.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char first[20]; 6 | char last[20]; 7 | 8 | printf("Enter a first and last name: "); 9 | scanf("%20s %20s", &first, &last); 10 | 11 | printf("You entered the name: %s, %c.\n", last, first[0]); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /08/8.14.reverse-sentence.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SPACE 0x20 4 | 5 | int main(void) 6 | { 7 | int boundary, i; 8 | char ch; 9 | char final_punctuation = 0; 10 | char sentence[255]; 11 | 12 | printf("Enter a sentence: "); 13 | 14 | for (i = 0; (ch = getchar()) != '\n'; i++) { 15 | sentence[i] = ch; 16 | } 17 | /* terminate the string */ 18 | sentence[i] = '\0'; 19 | 20 | /* 21 | * back up, point to last character before the newline, which was not stored 22 | */ 23 | i--; 24 | ch = sentence[i]; 25 | if (ch == '.' || ch == '?' || ch == '!') { 26 | final_punctuation = ch; 27 | /* replace the punc. char to simplify the code below */ 28 | sentence[i] = '\0'; 29 | } 30 | 31 | while (i >= 0) { 32 | /* word boundary or start of string */ 33 | if (sentence[i] == SPACE || i == 0) { 34 | boundary = i; 35 | 36 | /* if this is not the beginning of the string, 37 | * we need to point to the next char 38 | */ 39 | if (sentence[i] == SPACE) 40 | i++; 41 | /* Print the word */ 42 | while (sentence[i] != SPACE && sentence[i] != '\0') { 43 | printf("%c", sentence[i]); 44 | i++; 45 | } 46 | 47 | /* rewind to before the word we just printed */ 48 | i = boundary; 49 | if (i == 0) { // we've just printed the last (originally first) word 50 | if (final_punctuation) 51 | printf("%c", final_punctuation); 52 | } else { // we've just printed any of the other words 53 | printf("%c", SPACE); 54 | } 55 | } 56 | i--; 57 | } 58 | printf("\n"); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /08/8.15.ceasar-cipher.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char message[80]; 7 | char ch; 8 | int i, length, shift_amount; 9 | 10 | printf("Enter message to be encrypted: "); 11 | 12 | for (i = 0; (ch = getchar()) != '\n'; i++) { 13 | message[i] = ch; 14 | } 15 | length = i; 16 | 17 | printf("Enter shift amount (1-25): "); 18 | scanf("%d", &shift_amount); 19 | 20 | printf("Encrypted message: "); 21 | 22 | for (i = 0; i < length; i++) { 23 | ch = message[i]; 24 | if (ch >= 'a' && ch <= 'z') 25 | ch = (( ch - 'a') + shift_amount) % 26 + 'a'; 26 | if (ch >= 'A' && ch <= 'Z') 27 | ch = (( ch - 'A') + shift_amount) % 26 + 'A'; 28 | 29 | printf("%c", ch); 30 | } 31 | puts(""); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /08/8.16.anagram-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SIZE 28 6 | 7 | bool are_anagrams(const char *word1, const char *word2) 8 | { 9 | int letter_counts[26] = {0}; 10 | 11 | while (*word1) { 12 | if (isalpha(*word1)) 13 | letter_counts[tolower(*word1) - 'a']++; 14 | word1++; 15 | } 16 | 17 | while (*word2) { 18 | if (isalpha(*word2)) 19 | letter_counts[tolower(*word2) - 'a']--; 20 | word2++; 21 | } 22 | 23 | /* find a nonzero value */ 24 | for (int i = 0; i < 26; i++) { 25 | if (letter_counts[i] != 0) 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | void read_word(char *w, int n) 32 | { 33 | char ch, *p; 34 | for (p = w;(ch = getchar()) != '\n'; p++) 35 | if (p < (w + n)) 36 | *p = ch; 37 | 38 | *p = '\0'; 39 | } 40 | 41 | int main(void) 42 | { 43 | char w1[SIZE], w2[SIZE]; 44 | 45 | printf("Enter the first word: "); 46 | read_word(w1, SIZE); 47 | 48 | printf("Enter the second word: "); 49 | read_word(w2, SIZE); 50 | 51 | if (are_anagrams(w1, w2)) 52 | printf("The words are anagrams\n"); 53 | else 54 | printf("The words are not anagrams\n"); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /08/8.2.6-seven-segment.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | /* 6 | * 7 | * 8 | Segment Numbering: 9 | 10 | 0 11 | --- 12 | 5| |1 13 | | 6 | 14 | --- 15 | 4| |2 16 | | 3 | 17 | --- 18 | 19 | */ 20 | const int segments[10][7] = { 21 | {1, 1, 1, 1, 1, 1, 0}, // 0 22 | {0, 1, 1, 0, 0, 0, 0}, // 1 23 | {1, 1, 0, 1, 1, 0, 1}, // 2 24 | {1, 1, 1, 1, 0, 0, 1}, // 3 25 | {0, 1, 1, 0, 0, 1, 1}, // 4 26 | {1, 0, 1, 1, 0, 1, 1}, // 5 27 | {1, 0, 1, 1, 1, 1, 1}, // 6 28 | {1, 1, 1, 1, 0, 0, 0}, // 7 29 | {1, 1, 1, 1, 1, 1, 1}, // 8 30 | {1, 1, 1, 1, 0, 1, 1} // 9 31 | }; 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /08/8.6.jerk-filter.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SIZE 255 5 | int main(void) 6 | { 7 | int i; 8 | char message[SIZE]; 9 | char ch; 10 | 11 | printf("Enter message: "); 12 | for (i = 0; i < SIZE && (ch = getchar()) != '\n'; i++) { 13 | message[i] = ch; 14 | } 15 | message[i] = '\0'; 16 | 17 | printf("In J3rk-speak: "); 18 | for (i = 0; message[i] != '\0';i++) { 19 | ch = toupper(message[i]); 20 | switch (ch) { 21 | case 'A': 22 | ch = '4'; 23 | break; 24 | case 'B': 25 | ch = '8'; 26 | break; 27 | case 'E': 28 | ch = '3'; 29 | break; 30 | case 'I': 31 | ch = '1'; 32 | break; 33 | case 'L': 34 | ch = '1'; 35 | break; 36 | case 'O': 37 | ch = '0'; 38 | break; 39 | case 'S': 40 | ch = '5'; 41 | break; 42 | } 43 | printf("%c", ch); 44 | } 45 | printf("!!!!!!!!!!!!\n"); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /08/8.7-matrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define ROWS 5 3 | #define COLS 5 4 | #define NEWLINE printf("\n") 5 | 6 | int main(void) 7 | { 8 | int table[ROWS][COLS] = {{0}}; 9 | int row, col, total; 10 | 11 | for (row = 0; row < ROWS; row++) { 12 | printf("Enter row %d: ", row + 1); 13 | for (col = 0; col < COLS; col++) 14 | scanf("%d", &table[row][col]); 15 | } 16 | 17 | NEWLINE; 18 | printf("Row Totals:\t"); 19 | for (row = 0; row < ROWS; row++) { 20 | total = 0; 21 | for (col = 0; col < COLS; col++) { 22 | total += table[row][col]; 23 | } 24 | printf(" %5d", total); 25 | } 26 | NEWLINE; 27 | 28 | printf("Column Totals:\t"); 29 | for (col = 0; col < COLS; col++) { 30 | total = 0; 31 | for (row = 0; row < ROWS; row++) { 32 | total += table[row][col]; 33 | } 34 | printf(" %5d", total); 35 | } 36 | NEWLINE; 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /08/8.8-quiz-stats.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define STUDENTS 5 3 | #define QUIZES 5 4 | #define NEWLINE printf("\n") 5 | 6 | int main(void) 7 | { 8 | int table[STUDENTS][QUIZES] = {{0}}; 9 | int row, col, score, total, low, high; 10 | 11 | printf("Enter quiz scores:\n"); 12 | for (row = 0; row < STUDENTS; row++) { 13 | printf("Student %d: ", row + 1); 14 | for (col = 0; col < QUIZES; col++) 15 | scanf("%d", &table[row][col]); 16 | } 17 | 18 | NEWLINE; 19 | printf("Student Stats:\tAverage\tTotal\n"); 20 | for (row = 0; row < STUDENTS; row++) { 21 | printf("Student %d:", row + 1); 22 | total = 0; 23 | for (col = 0; col < QUIZES; col++) { 24 | total += table[row][col]; 25 | } 26 | printf("\t%4d\t%4d\n", total / QUIZES, total); 27 | } 28 | NEWLINE; 29 | 30 | printf("Quiz Stats:\tLow\tHigh\tAverage\n"); 31 | for (col = 0; col < QUIZES; col++) { 32 | printf("Quiz %d:\t", col + 1); 33 | total = 0; 34 | high = 0; 35 | low = 100; 36 | for (row = 0; row < STUDENTS; row++) { 37 | score = table[row][col]; 38 | if (score > high) 39 | high = score; 40 | if (score < low) 41 | low = score; 42 | total += score; 43 | } 44 | printf("\t%4d\t%4d\t%4d\n", low, high, total / STUDENTS); 45 | } 46 | NEWLINE; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /08/interest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NUM_RATES ((int) (sizeof(value) / sizeof(value[0]))) 4 | #define INITIAL_BALANCE 100.00 5 | 6 | int main(void) 7 | { 8 | int i, m, low_rate, num_years, year; 9 | /*hold 5 balances: a working value for each of 5 rates we'll be compounding*/ 10 | double value[5]; 11 | 12 | printf("Enter interest rate: "); 13 | scanf("%d", &low_rate); 14 | printf("Enter number of years: "); 15 | scanf("%d", &num_years); 16 | 17 | printf("\nYears"); 18 | for (i = 0; i < NUM_RATES; i++) { 19 | /* calculate the 4 remaining rates*/ 20 | /* and display the 5 rates in a header row*/ 21 | printf("%6d%%", low_rate + i); 22 | /*for each rate, initialize its working array element to $100.00*/ 23 | value[i] = INITIAL_BALANCE; 24 | } 25 | printf("\n"); 26 | 27 | for (year = 1; year <= num_years; year++) { 28 | printf("%3d ", year); 29 | for (i = 0; i < NUM_RATES; i++ ) { 30 | /*to begin the series of monthly balance calcuations, save off the previous year's balance*/ 31 | /*for the rate we're currently on*/ 32 | for (m = 0; m < 12; m++) { 33 | value[i] += ((( low_rate + i) / 100.00) / 12.0) * value[i]; 34 | } 35 | /*accumulated balance for a year of 12 monthtly calcuations: save for display and to seed next year's calc for this rate*/ 36 | printf("%7.2f", value[i]); 37 | } 38 | printf("\n"); 39 | } 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /08/repdigit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define DIGIT_FORMAT "%3d" 3 | #define NUM_DIGITS 10 4 | int main(void) 5 | { 6 | int digit_counts[NUM_DIGITS]; 7 | int digit; 8 | long n; 9 | 10 | printf("Enter a number (0 or negative to terminate: "); 11 | while (scanf("%ld", &n), (n > 0)) { 12 | for (digit = 0; digit < NUM_DIGITS; digit++) { 13 | digit_counts[digit] = 0; 14 | } 15 | 16 | while (n > 0) { 17 | digit = n % 10; 18 | digit_counts[digit]++; 19 | n /= 10; 20 | } 21 | 22 | printf("Digit:\t\t"); 23 | for (digit = 0; digit < NUM_DIGITS; digit++) { 24 | printf(DIGIT_FORMAT, digit); 25 | } 26 | puts(""); 27 | 28 | printf("Occurrences:\t"); 29 | for (digit = 0; digit < NUM_DIGITS; digit++) { 30 | printf(DIGIT_FORMAT, digit_counts[digit]); 31 | } 32 | puts(""); 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /08/reverse.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define N 10 3 | #define SIZE (int) (sizeof(a) / sizeof(a[0])) 4 | int main(void) 5 | { 6 | int a[N], i; 7 | 8 | printf("Enter %d numbers: ", N); 9 | for (i = 0; i < SIZE; i++) 10 | scanf("%d", &a[i]); 11 | 12 | printf("And now, in reverse order!: "); 13 | for (i = SIZE - 1; i >= 0; i--) 14 | printf(" %d", a[i]); 15 | 16 | puts(""); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /09/9.1.function_exercises.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int check(int x, int y, int n) 4 | { 5 | return x >= 0 && x < n && y >= 0 && y < n; 6 | } 7 | 8 | int gcd(int m, int n) 9 | { 10 | int r; 11 | while (n != 0) { 12 | r = m % n; 13 | m = n; 14 | n = r; 15 | } 16 | return m; 17 | } 18 | 19 | int day_of_year(int m, int d, int yyyy) 20 | { 21 | int month_lengths[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 22 | int i, days = 0; 23 | 24 | /*leap year?*/ 25 | if ((yyyy % 4 == 0 && yyyy % 100 != 0) || yyyy % 400 == 0) 26 | month_lengths[1] = 29; 27 | 28 | /*accumulate all the days in each preceding month*/ 29 | for (i = 0; i < m - 1; i++) 30 | days += month_lengths[i]; 31 | 32 | return days + d; 33 | } 34 | 35 | int main(void) 36 | { 37 | int int1, int2, int3; 38 | 39 | printf("Exercise 9.2 - enter x, y, and n: "); 40 | scanf("%d %d %d", &int1, &int2, &int3); 41 | printf("Are x and y between 0 and n? %d\n", check(int1, int2, int3)); 42 | 43 | printf("Exercise 9.3 - enter m and n: "); 44 | scanf("%d %d", &int1, &int2); 45 | printf("Greatest Common Divisor: %d\n", gcd(int1, int2)); 46 | 47 | printf("Exercise 9.4 - enter a date as mm/dd/yyyy: "); 48 | scanf("%d/%d/%d", &int1, &int2, &int3); 49 | printf("Day of Year: %d\n", day_of_year(int1, int2, int3)); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /09/9.3.10.array_value_functions.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int max(int a[], int n); 4 | int avg(int a[], int n); 5 | int positive_count(int a[], int n); 6 | 7 | int main(void) 8 | { 9 | int array[] = {12, 31, 0, 15, 2, 99, 1024, 8, 512, -299}; 10 | 11 | int size = ((int) (sizeof(array) / sizeof(array[0]))); 12 | printf("Max: %d\n", max(array, size)); 13 | printf("Average: %d\n", avg(array, size)); 14 | printf("Positive count: %d of %d\n", positive_count(array, size), size); 15 | return 0; 16 | } 17 | 18 | int max(int a[], int n) 19 | { 20 | int i, m = a[0]; 21 | for (i = 1; i < n; i++) { 22 | if (a[i] > m) 23 | m = a[i]; 24 | } 25 | return m; 26 | } 27 | int avg(int a[], int n) 28 | { 29 | int i, sum = 0; 30 | for (i = 0; i < n; i++) 31 | sum += a[i]; 32 | 33 | return sum / n; 34 | } 35 | int positive_count(int a[], int n) 36 | { 37 | int i, count = 0; 38 | for (i = 0; i < n; i++) { 39 | if (a[i] > 0) 40 | count++; 41 | } 42 | 43 | return count; 44 | } 45 | -------------------------------------------------------------------------------- /09/9.3.11.gpa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SIZE 100 6 | float compute_GPA(char grades[], int n); 7 | 8 | int main(void) 9 | { 10 | char ch, grades[SIZE]; 11 | int i = 0; 12 | printf("Enter up to %d letter grades: ", SIZE); 13 | 14 | while ((ch = getchar()) != '\n' && i < SIZE) { 15 | if (ch != ' ') { 16 | grades[i] = ch; 17 | i++; 18 | } 19 | } 20 | 21 | printf("GPA: %.2f\n", compute_GPA(grades, i)); 22 | return 0; 23 | } 24 | 25 | float compute_GPA(char grades[], int n) 26 | { 27 | float sum = 0.0; 28 | int i; 29 | 30 | for (i = 0; i < n; i++) { 31 | switch(toupper(grades[i])) { 32 | case 'A': 33 | sum += 4.0f; 34 | break; 35 | case 'B': 36 | sum += 3.0f; 37 | break; 38 | case 'C': 39 | sum += 2.0f; 40 | break; 41 | case 'D': 42 | sum += 1.0f; 43 | break; 44 | case 'F': 45 | sum += 0.0f; 46 | break; 47 | default: 48 | fprintf(stderr, "Invalid input: %c\n", grades[i]); 49 | exit(1); 50 | } 51 | } 52 | return sum / (float) n; 53 | } 54 | -------------------------------------------------------------------------------- /09/9.4.anagram-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SIZE 26 6 | void read_word(int letter_counts[]); 7 | bool arrays_equal(int letter_counts[], int other[]); 8 | 9 | int main(void) 10 | { 11 | int letter_counts1[SIZE] = {0}; 12 | int letter_counts2[SIZE] = {0}; 13 | 14 | printf("Enter the first word: "); 15 | read_word(letter_counts1); 16 | 17 | printf("Enter the second word: "); 18 | read_word(letter_counts2); 19 | 20 | if (arrays_equal(letter_counts1, letter_counts2)) 21 | printf("The words are anagrams\n"); 22 | else 23 | printf("The words are not anagrams\n"); 24 | 25 | return 0; 26 | } 27 | 28 | void read_word(int letter_counts[]) 29 | { 30 | char ch; 31 | while ((ch = getchar()) != '\n') { 32 | if (isalpha(ch)) 33 | letter_counts[tolower(ch) - 'a']++; 34 | } 35 | } 36 | bool arrays_equal(int letter_counts[], int other[]) 37 | { 38 | int i; 39 | /*find a nonzero value*/ 40 | for (i = 0; i < SIZE; i++) { 41 | if (letter_counts[i] != other[i]) 42 | break; 43 | } 44 | return i == SIZE ? true : false; 45 | } 46 | -------------------------------------------------------------------------------- /10/10.1.3.scope.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int i = 0; 4 | 5 | int main(void) 6 | { 7 | printf("Global %d\n", i); 8 | int i = 1; 9 | printf("Main %d\n", i); 10 | 11 | { 12 | printf("First Block %d\n", i); 13 | int i = 2; 14 | printf("First Block %d\n", i); 15 | 16 | { 17 | printf("Second Block %d\n", i); 18 | int i = 3; 19 | printf("Second Block %d\n", i); 20 | { 21 | printf("Innermost Block %d\n", i); 22 | int i = 4; 23 | printf("Innermost Block %d\n", i); 24 | } 25 | } 26 | } 27 | 28 | printf("Main %d\n", i); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /11/11.1.currency-denominations.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void pay_amount(int, int*, int*, int*, int*); 4 | 5 | int main(void) 6 | { 7 | int amount, twenties, tens, fives, ones; 8 | 9 | printf("Enter a dollar amount: "); 10 | scanf("%d", &amount); 11 | 12 | pay_amount(amount, &twenties, &tens, &fives, &ones); 13 | 14 | printf("$20 bills: %d\n", twenties); 15 | printf("$10 bills: %d\n", tens); 16 | printf("$5 bills: %d\n", fives); 17 | printf("$1 bills: %d\n", ones); 18 | 19 | return 0; 20 | } 21 | 22 | void pay_amount(int dollars, int* twenties, int* tens, int* fives, int* ones) 23 | { 24 | int remainder; 25 | 26 | *twenties = dollars / 20; 27 | remainder = dollars % 20; 28 | *tens = remainder / 10; 29 | remainder = remainder % 10; 30 | *fives = remainder / 5; 31 | remainder = remainder % 5; 32 | *ones = remainder; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /11/11.4.4.swap.c: -------------------------------------------------------------------------------- 1 | void swap(int *p, int *q) 2 | { 3 | int tmp; 4 | tmp = *p; 5 | *p = *q; 6 | *q = tmp; 7 | } 8 | 9 | int main(void) 10 | { 11 | int i, j; 12 | i = 12; 13 | j = 100; 14 | 15 | swap(&i, &j); 16 | return 0; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /11/11.4.5.split_time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void split_time(long total_sec, int *hr, int *min, int *sec) 6 | { 7 | *hr = total_sec / ( 60 * 60 ); 8 | *min = total_sec % ( 60 * 60 ) / 60; 9 | *sec = total_sec % 60; 10 | } 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | int hr, min, sec; 15 | 16 | if (argc > 1) { 17 | /* 1 hour, 1 min, 1 sec */ 18 | split_time(atoi(argv[1]), &hr, &min, &sec); 19 | printf("%d:%d:%d\n", hr, min, sec); 20 | } 21 | 22 | /* now */ 23 | split_time(time(NULL), &hr, &min, &sec); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /11/11.4.6.two_largest.c: -------------------------------------------------------------------------------- 1 | 2 | void two_largest(int [], int, int*, int*); 3 | 4 | int main(void) 5 | { 6 | int max, second; 7 | 8 | two_largest((int []) {10, 9, 312, 569, 1, 311}, 6, &max, &second); 9 | return 0; 10 | } 11 | 12 | void two_largest(int a[], int n, int *largest, int *second) 13 | { 14 | *largest = *second = 0; 15 | for (int i = 0; i < n; i++) { 16 | if (a[i] > *largest) { 17 | *second = *largest; 18 | *largest = a[i]; 19 | } else if (a[i] > *second) 20 | *second = a[i]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /11/11.4.7.split_date.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void split_date(int day_of_year, int year, int *month, int *day) 5 | { 6 | int eom[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 7 | int previous_month_end, current_month_end; 8 | 9 | /*leap year?*/ 10 | if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) 11 | eom[2] = 29; 12 | 13 | previous_month_end = 0; 14 | *month = 1; 15 | current_month_end = eom[*month]; 16 | /* 17 | * Find the closest month end by looping 18 | * until we are between the previous EOM and the EOM of our day_of_year 19 | */ 20 | while (!(day_of_year > previous_month_end && day_of_year <= current_month_end)) { 21 | previous_month_end = current_month_end; 22 | current_month_end += eom[++*month]; 23 | } 24 | *day = day_of_year - previous_month_end; 25 | } 26 | 27 | int main(int argc, char *argv[]) 28 | { 29 | int dd, yyyy, month, day; 30 | 31 | if (argc != 3) { 32 | fprintf(stderr, "Usage: $ %s
\n", argv[0]); 33 | return 1; 34 | } 35 | 36 | dd = atoi(argv[1]); 37 | yyyy = atoi(argv[2]); 38 | split_date(dd, yyyy, &month, &day); 39 | 40 | printf("%d, %d: %.2d/%.2d\n", yyyy, dd, month, day); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /11/11.5.8.pointer_to_largest.c: -------------------------------------------------------------------------------- 1 | int *find_largest(int a[], int n) 2 | { 3 | int index_of_max = 0; 4 | int max = a[index_of_max]; 5 | for (int i = 1; i < n; i++) { 6 | if (a[i] > max) { 7 | max = a[i]; 8 | index_of_max = i; 9 | } 10 | } 11 | 12 | return &a[index_of_max]; 13 | } 14 | 15 | int main(void) 16 | { 17 | 18 | int *m = find_largest((int []) {89, 2, 345, 101}, 4); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /12/12.1.2.low-middle-high.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int a[] = {0, 1, 2, 3, 4, 5}, *low, *middle, *high; 6 | 7 | low = a; 8 | high = &a[5]; 9 | 10 | 11 | printf("low: %p, %d\n", low, *low); 12 | printf("high: %p, %d\n", high, *high); 13 | 14 | middle = low + (high - low) / 2; 15 | 16 | printf("middle: %p, %d\n", middle, *middle); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /12/12.1.reverse.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SIZE 25 4 | int main(void) 5 | { 6 | char ch, message[SIZE]; 7 | char *ptr; 8 | printf("Enter a message up to %d characters: ", SIZE); 9 | for (ptr = message; ptr < message + SIZE && (ch = getchar()) != '\n'; ptr++) 10 | *ptr = ch; 11 | 12 | printf("Reversed: "); 13 | for (; ptr >= message; ptr--) 14 | printf("%c", *ptr); 15 | 16 | printf("\n"); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /12/12.2.3.reverse.c: -------------------------------------------------------------------------------- 1 | #define N 10 2 | int main(void) 3 | { 4 | int a[N] = {1,2,3,4,5,6,7,8,9,10}; 5 | int *p = a, *q = &a[N-1], temp; 6 | 7 | while (p < q) 8 | { 9 | temp = *p; 10 | *p++ = *q; 11 | *q-- = temp; 12 | } 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /12/12.2.4.stack_functions.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define STACK_SIZE 100 4 | int contents[STACK_SIZE]; 5 | int *top_ptr = contents; 6 | 7 | void empty(void); 8 | bool is_empty(void); 9 | bool is_full(void); 10 | 11 | int main(void) 12 | { 13 | return 0; 14 | } 15 | 16 | void empty(void) 17 | { 18 | top_ptr = contents; 19 | /* top_ptr = &contents[0]; */ 20 | } 21 | bool is_empty(void) 22 | { 23 | return top_ptr == contents; 24 | /* return top_ptr == &contents[0]; */ 25 | } 26 | bool is_full(void) 27 | { 28 | return top_ptr == &contents[STACK_SIZE]; 29 | } 30 | -------------------------------------------------------------------------------- /12/12.2.palindrome.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SIZE 120 6 | bool is_palindrome(char *a, int n); 7 | 8 | int main(void) 9 | { 10 | char ch, message[SIZE]; 11 | 12 | int i = 0; 13 | printf("Enter a phrase, perhaps palindromic: "); 14 | 15 | while (i < SIZE && (ch = getchar()) != '\n') 16 | if (isalpha(ch)) 17 | message[i++] = toupper(ch); 18 | 19 | if (is_palindrome(message, i - 1)) 20 | printf("Palindrome Detected, Captain!\n"); 21 | else 22 | printf("No Palindrome found, Sir!\n"); 23 | 24 | return 0; 25 | } 26 | 27 | bool is_palindrome(char *a, int n) 28 | { 29 | char *left, *right; 30 | for (left = a, right = a + n; left <= right; left++, right--) 31 | if (*left != *right) 32 | return false; 33 | 34 | return true; 35 | } 36 | -------------------------------------------------------------------------------- /12/12.3.10.find-middle.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int *find_middle(int *a, int n) 4 | { 5 | /* return a + (((a + n) - a) / 2); */ 6 | int *low_ptr = a; 7 | int *high_ptr = low_ptr + n; 8 | 9 | return low_ptr + ((high_ptr - low_ptr) / 2); 10 | } 11 | 12 | int main(void) 13 | { 14 | int ar[9] = {0,1,2,3,4,5,6,7,8}; 15 | 16 | int *mid_ptr = find_middle(ar+3, 9); 17 | 18 | printf("%p: %d\n", mid_ptr, *mid_ptr); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /12/12.3.11.find-largest.c: -------------------------------------------------------------------------------- 1 | int *find_largest(int *a, int n) 2 | { 3 | int *a_ptr, *max_ptr; 4 | max_ptr = a; 5 | for (a_ptr = a; a_ptr < a + n; a_ptr++) { 6 | if (*a_ptr > *max_ptr) 7 | max_ptr = a_ptr; 8 | } 9 | 10 | return max_ptr; 11 | } 12 | 13 | int main(void) 14 | { 15 | 16 | int *m = find_largest((int []) {89, 2, 345, 101}, 4); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /12/12.3.12.two-largest.c: -------------------------------------------------------------------------------- 1 | void find_two_largest(const int *a, int n, int *largest, int *second) 2 | { 3 | const int *a_ptr; 4 | *largest = *second = 0; 5 | for (a_ptr = a; a_ptr < a + n; a_ptr++) { 6 | if (*a_ptr > *largest) { 7 | *second = *largest; 8 | *largest = *a_ptr; 9 | } else if (*a_ptr > *second) 10 | *second = *a_ptr; 11 | } 12 | } 13 | 14 | int main(void) 15 | { 16 | int max, second; 17 | 18 | find_two_largest((int []) {10, 9, 312, 569, 1, 311}, 6, &max, &second); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /12/12.3.6.refactor-to-pointer-arithmetic.c: -------------------------------------------------------------------------------- 1 | int sum_array(const int a[], int n) 2 | { 3 | int sum; 4 | const int *p; 5 | 6 | sum = 0; 7 | for (p = a; p < a + n; p++) 8 | sum += *p; 9 | return sum; 10 | 11 | } 12 | 13 | int main(void) 14 | { 15 | int numbers[] = {12,34,56,78,99}; 16 | 17 | int total = sum_array(&numbers[2], 2); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /12/12.3.8.clear.c: -------------------------------------------------------------------------------- 1 | void store_zeroes(int a[], int n) 2 | { 3 | int *pa; 4 | for (pa = a; pa < a + n; pa++) 5 | *pa = 0; 6 | } 7 | 8 | int main(void) 9 | { 10 | int a[76]; 11 | 12 | store_zeroes(a, 76); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /12/12.3.9.inner-product.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SIZE 5 4 | double inner_product(const double *a, const double *b, int n) 5 | { 6 | const double *a_ptr, *b_ptr; 7 | double product = 0.0; 8 | 9 | for (a_ptr = a, b_ptr = b; a_ptr < a + n && b_ptr < b + n; a_ptr++, b_ptr++) 10 | product += *a_ptr * *b_ptr; 11 | return product; 12 | } 13 | 14 | int main(void) 15 | { 16 | double ar1[SIZE] = {1.0, 3.145, 7.8, -22.05, 99.99}; 17 | double ar2[SIZE] = {3.0, 1.15, 8.8, -22.05, 19.099}; 18 | 19 | printf("Product: %3.8f\n", inner_product(ar1, ar2, SIZE)); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /12/12.4.13.identity-matrix.c: -------------------------------------------------------------------------------- 1 | #define N 12 2 | int main(void) 3 | { 4 | double identity_matrix[N][N]; 5 | double *e; 6 | int zeroes = N; 7 | 8 | for (e = &identity_matrix[0][0]; e <= &identity_matrix[N-1][N-1]; e++) 9 | if (zeroes == N) { 10 | zeroes = 0; 11 | *e = 1.1; 12 | } else { 13 | zeroes++; 14 | *e = 0.0; 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /12/12.7-maxmin.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* maxmin.c (Chapter 11, page 250) */ 11 | /* Finds the largest and smallest elements in an array */ 12 | 13 | #include 14 | 15 | #define N 10 16 | 17 | void max_min(int a[], int n, int *max, int *min); 18 | 19 | int main(void) 20 | { 21 | int b[N], i, big, small; 22 | 23 | printf("Enter %d numbers: ", N); 24 | for (i = 0; i < N; i++) 25 | scanf("%d", &b[i]); 26 | 27 | max_min(b, N, &big, &small); 28 | 29 | printf("Largest: %d\n", big); 30 | printf("Smallest: %d\n", small); 31 | 32 | return 0; 33 | } 34 | 35 | void max_min(int a[], int n, int *max, int *min) 36 | { 37 | int *p; 38 | 39 | *max = *min = a[0]; 40 | for (p = &a[1]; p < a + n; p++) { 41 | if (*p > *max) 42 | *max = *p; 43 | else if (*p < *min) 44 | *min = *p; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /13/13.1-smallest-largest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SIZE 20 5 | 6 | int main(void) 7 | { 8 | 9 | char word[SIZE + 1]; 10 | char smallest[SIZE + 1] = {127}; 11 | char largest[SIZE + 1]; 12 | 13 | while (strlen(word) != 4) { 14 | printf("Enter a word: "); 15 | scanf("%20s", word); 16 | 17 | if (strcmp(word, smallest) < 0) 18 | strncpy(smallest, word, SIZE); 19 | else if (strcmp(word, largest) > 0) 20 | strncpy(largest, word, SIZE); 21 | } 22 | 23 | printf("Lowest word: %s\n", smallest); 24 | printf("Highest word: %s\n", largest); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /13/13.10-reverse-name.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SIZE 64 5 | void reverse_name(char *name); 6 | 7 | int main(void) 8 | { 9 | char name[SIZE + 1]; 10 | printf("Enter First Name and Last Name: "); 11 | fgets(name, sizeof(name), stdin); 12 | 13 | reverse_name(name); 14 | 15 | puts(name); 16 | return 0; 17 | } 18 | void reverse_name(char *name) 19 | { 20 | /* char first[SIZE / 2], last[SIZE / 2]; */ 21 | 22 | /* sscanf(name, " %s %s", first, last); */ 23 | 24 | /* sprintf(name, "%s, %c.", last, first[0]); */ 25 | 26 | char first, *p = name; 27 | int len; 28 | while (*p && *p == ' ') p++; /* find first non-space character */ 29 | first = *p; 30 | while (*p && *p != ' ') p++; /* find word boundary: first space after first p */ 31 | while (*p && *p == ' ') p++; /* find start of last */ 32 | for (len = 0; p[len] != '\n' && p[len] && p[len] != ' '; len++); 33 | sprintf(name, "%.*s, %c.", len, p, first); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /13/13.13-ceasar-cipher.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void encrypt(char *s, int shift) 5 | { 6 | for (; *s; s++) { 7 | if (islower(*s)) 8 | *s = (( *s - 'a') + shift) % 26 + 'a'; 9 | if (isupper(*s)) 10 | *s = (( *s - 'A') + shift) % 26 + 'A'; 11 | } 12 | } 13 | 14 | #define SIZE ( (int) (sizeof(message) / sizeof(message[0])) ) 15 | 16 | int main(void) 17 | { 18 | char message[80]; 19 | char ch; 20 | int i, shift_amount; 21 | 22 | printf("Enter message to be encrypted: "); 23 | 24 | for (i = 0; i < SIZE && (ch = getchar()) != '\n'; i++) { 25 | message[i] = ch; 26 | } 27 | message[i] = '\0'; 28 | 29 | printf("Enter shift amount (1-25): "); 30 | scanf("%d", &shift_amount); 31 | 32 | encrypt(message, shift_amount); 33 | printf("Encrypted message: %s\n", message); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /13/13.3-deal.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* deal.c (Chapter 8, page 173) */ 11 | /* Deals a random hand of cards */ 12 | 13 | #include /* C99 only */ 14 | #include 15 | #include 16 | #include 17 | 18 | #define NUM_SUITS 4 19 | #define NUM_RANKS 13 20 | 21 | int main(void) 22 | { 23 | bool in_hand[NUM_SUITS][NUM_RANKS] = {{false}}; 24 | int num_cards, rank, suit; 25 | const char *rank_name[] = {"Two","Three","Four","Five","Six","Seven","Eight", 26 | "Nine","Ten","Jack","Queen","King","Ace"}; 27 | const char *suit_name[] = {"Clubs","Diamonds","Hearts","Spades"}; 28 | 29 | srand((unsigned) time(NULL)); 30 | 31 | printf("Enter number of cards in hand: "); 32 | scanf("%d", &num_cards); 33 | 34 | printf("Your hand:\n"); 35 | while (num_cards > 0) { 36 | suit = rand() % NUM_SUITS; /* picks a random suit */ 37 | rank = rand() % NUM_RANKS; /* picks a random rank */ 38 | if (!in_hand[suit][rank]) { 39 | in_hand[suit][rank] = true; 40 | num_cards--; 41 | printf("%s of %s\n", rank_name[rank], suit_name[suit]); 42 | } 43 | } 44 | printf("\n"); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /13/13.3.1-single-newline.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("%c", '\n'); 6 | printf("%c", "\n"); 7 | /* printf("%s", '\n'); */ 8 | /* 9 | Program received signal SIGSEGV, Segmentation fault. 10 | 0x00007ffff7a98cba in _IO_vfprintf_internal (s=0x7ffff7dd77a0, format=0x400701 "%s", ap=0x7fffffffe150) at vfprintf.c:1623 11 | 1623 vfprintf.c: No such file or directory. 12 | (gdb) where 13 | #0 0x00007ffff7a98cba in _IO_vfprintf_internal (s=0x7ffff7dd77a0, format=0x400701 "%s", ap=0x7fffffffe150) at vfprintf.c:1623 14 | #1 0x00007ffff7aa147a in __printf (format=0x400702 "s") at printf.c:35 15 | #2 0x00000000004005d6 in main () at 13/13.3.1-single-newline.c:7 16 | */ 17 | 18 | 19 | 20 | printf("%s", "\n"); 21 | /* printf('\n'); */ 22 | /* 23 | Program received signal SIGSEGV, Segmentation fault. 24 | strchrnul () at ../sysdeps/x86_64/strchrnul.S:34 25 | 34 ../sysdeps/x86_64/strchrnul.S: No such file or directory. 26 | (gdb) where 27 | #0 strchrnul () at ../sysdeps/x86_64/strchrnul.S:34 28 | #1 0x00007ffff7a9671f in __find_specmb (format=) at printf-parse.h:99 29 | #2 _IO_vfprintf_internal (s=0x7ffff7dd77a0, format=0xa
, ap=0x7fffffffe150) at vfprintf.c:1328 30 | #3 0x00007ffff7aa147a in __printf (format=0xffffffff
) at printf.c:35 31 | #4 0x00000000004005db in main () at 13/13.3.1-single-newline.c:21 32 | */ 33 | putchar('\n'); 34 | putchar("\n"); 35 | /* 13/13.3.1-single-newline.c|34 col 3 warning| passing argument 1 of ‘putchar’ makes integer from pointer without a cast [enabled by default] */ 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /13/13.3.2-pointer-to-string.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | 6 | char *p = "abc"; 7 | 8 | putchar(*p); 9 | putchar(p); 10 | /* 13/13.3.2-pointer-to-string.c|9 col 3 warning| passing argument 1 of ‘putchar’ makes integer from pointer without a cast [enabled by default] */ 11 | /* puts(*p); */ 12 | /* 13 | Program received signal SIGSEGV, Segmentation fault. 14 | __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:32 15 | 32 ../sysdeps/x86_64/multiarch/../strlen.S: No such file or directory. 16 | (gdb) where 17 | #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:32 18 | #1 0x00007ffff7abd07b in _IO_puts (str=0x61
) at ioputs.c:37 19 | #2 0x000000000040058b in main () at 13/13.3.2-pointer-to-string.c:11 20 | */ 21 | 22 | puts(p); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /13/13.3.3-scanf.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int i, j; 6 | char s[15]; 7 | 8 | scanf("%d%s%d", &i, s, &j); 9 | 10 | printf("i: %d, j: %d, s: |%s|\n", i, j, s); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /13/13.3.4-read-line-no-whitespace.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define SIZE 80 4 | 5 | int read_line(char s[], int n); 6 | void print_header(char *header); 7 | 8 | int main(void) 9 | { 10 | char str[SIZE + 1]; 11 | int len; 12 | printf("Enter a string:\n"); 13 | print_header("+---------"); 14 | 15 | len = read_line(str, SIZE); 16 | printf("Your %d character string, Sir:\n%s\n", len, str); 17 | 18 | print_header("0123456789"); 19 | 20 | return 0; 21 | } 22 | 23 | /* Reads an entire line, but only stores up to n characters */ 24 | int read_line(char s[], int n) 25 | { 26 | int ch, i = 0; 27 | 28 | while ((ch = getchar()) != '\n' && !isspace(ch)) 29 | if (i < n) 30 | s[i++] = ch; 31 | 32 | s[i] = '\0'; 33 | 34 | return i; 35 | } 36 | void print_header(char *header) 37 | { 38 | for (int i = 0; i < SIZE / 10; i++) printf(header); 39 | puts(""); 40 | } 41 | -------------------------------------------------------------------------------- /13/13.3.4-read-line-truncate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define SIZE 20 4 | 5 | int read_line(char s[], int n); 6 | void print_header(char *header); 7 | 8 | int main(void) 9 | { 10 | char str1[SIZE + 1]; 11 | char str2[SIZE + 1]; 12 | printf("Enter a string:\n"); 13 | print_header("+---------"); 14 | 15 | printf("String 1 (%d):\n%s\n", read_line(str1, SIZE), str1); 16 | printf("String 2 (%d):\n%s\n", read_line(str2, SIZE), str2); 17 | 18 | print_header("0123456789"); 19 | 20 | return 0; 21 | } 22 | 23 | /* Reads a line up to n characters */ 24 | int read_line(char s[], int n) 25 | { 26 | int ch, i = 0; 27 | 28 | /* ignore leading whitespace */ 29 | while (isspace(ch = getchar())); 30 | 31 | /* the first non-whitespace character */ 32 | s[i++] = ch; 33 | 34 | while ((ch = getchar()) != '\n' && i < n) 35 | s[i++] = ch; 36 | 37 | s[i] = '\0'; 38 | 39 | return i; 40 | } 41 | void print_header(char *header) 42 | { 43 | for (int i = 0; i < SIZE / 10; i++) printf(header); 44 | puts(""); 45 | } 46 | -------------------------------------------------------------------------------- /13/13.3.4-read-line-with-newline.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define SIZE 80 4 | 5 | int read_line(char s[], int n); 6 | void print_header(char *header); 7 | 8 | int main(void) 9 | { 10 | char str[SIZE + 1]; 11 | int len; 12 | printf("Enter a string:\n"); 13 | print_header("+---------"); 14 | 15 | len = read_line(str, SIZE); 16 | printf("Your %d character string, Sir:\n%s\n", len, str); 17 | 18 | print_header("0123456789"); 19 | 20 | return 0; 21 | } 22 | 23 | /* Reads an entire line, but only stores up to n characters */ 24 | int read_line(char s[], int n) 25 | { 26 | int ch, i; 27 | 28 | /* ignore leading whitespace */ 29 | while (isspace(ch = getchar())); 30 | 31 | /* the first non-whitespace character */ 32 | s[0] = ch; 33 | 34 | i = 1; 35 | while ((ch = getchar()) != '\n') 36 | if (i < n) { 37 | s[i] = ch; 38 | i += 1; 39 | } 40 | 41 | /* store the newline if there's room */ 42 | if (i < n) { 43 | s[i] = ch; 44 | i += 1; 45 | } 46 | 47 | /* terminate the string */ 48 | s[i] = '\0'; 49 | 50 | return i; 51 | } 52 | void print_header(char *header) 53 | { 54 | for (int i = 0; i < SIZE / 10; i++) printf(header); 55 | puts(""); 56 | } 57 | -------------------------------------------------------------------------------- /13/13.3.4-read-line.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define SIZE 80 4 | 5 | int read_line(char s[], int n); 6 | void print_header(char *header); 7 | 8 | int main(void) 9 | { 10 | char str[SIZE + 1]; 11 | int len; 12 | printf("Enter a string:\n"); 13 | print_header("+---------"); 14 | 15 | len = read_line(str, SIZE); 16 | printf("Your %d character string, Sir:\n%s\n", len, str); 17 | 18 | print_header("0123456789"); 19 | 20 | return 0; 21 | } 22 | 23 | /* Reads an entire line, but only stores up to n characters */ 24 | int read_line(char s[], int n) 25 | { 26 | int ch, i = 0; 27 | 28 | /* ignore leading whitespace */ 29 | while (isspace(ch = getchar())); 30 | 31 | /* the first non-whitespace character */ 32 | s[i++] = ch; 33 | 34 | /* i should be 1 */ 35 | while ((ch = getchar()) != '\n') 36 | if (i < n) 37 | s[i++] = ch; 38 | 39 | s[i] = '\0'; 40 | 41 | return i; 42 | } 43 | void print_header(char *header) 44 | { 45 | for (int i = 0; i < SIZE / 10; i++) printf(header); 46 | puts(""); 47 | } 48 | -------------------------------------------------------------------------------- /13/13.4-reverse.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | if (argc < 3) { 6 | fprintf(stderr, "Use more than 1 argument\n"); 7 | } 8 | 9 | for (int i = argc - 1; i > 0; i--) 10 | printf("%s ", argv[i]); 11 | 12 | printf("\n"); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /13/13.4.5-capitalize.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void capitalize(char *str); 5 | 6 | int main(void) 7 | { 8 | char s[] = "what is wrong with you, lucille?"; 9 | 10 | printf("before:\v%s\n", s); 11 | capitalize(s); 12 | printf("after:\v%s\n", s); 13 | 14 | return 0; 15 | } 16 | 17 | void capitalize(char *str) 18 | { 19 | char *ch_ptr; 20 | for (ch_ptr = str; *ch_ptr != '\0'; ch_ptr++) 21 | *ch_ptr = toupper(*ch_ptr); 22 | } 23 | -------------------------------------------------------------------------------- /13/13.4.6-censor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void censor(char *source, char *target); 5 | 6 | int main(void) 7 | { 8 | char s[] = "Philo (a.k.a. \"Mr. Fuffoo Pants\") the foolish foodie found tofu profoundly fulfilling.\n"; 9 | char s1[] = "Roderick Riddick loved the films of Ernst Lubibitch (sic)."; 10 | 11 | printf("Before:\v%s\n", s); 12 | censor(s, "foo"); 13 | printf("After: \v%s\n", s); 14 | 15 | printf("Before:\v%s\n", s1); 16 | censor(s1, "dick"); 17 | censor(s1, "bitch"); 18 | printf("After: \v%s\n", s1); 19 | 20 | return 0; 21 | } 22 | 23 | /* mask out any occurrences of target in the source string */ 24 | void censor(char *source, char *target) 25 | { 26 | char *target_end = target + strlen(target); 27 | char *t, *s; 28 | for (s = source; *s != '\0'; s++) { 29 | for (t = target; t < target_end && *s == *t; s++, t++); 30 | 31 | if (t == target_end) { 32 | /* we had a full match: censor it! */ 33 | while (t > target) { 34 | /* walk forward, left to right */ 35 | *(s - (t - target)) = 'x'; 36 | t--; 37 | } 38 | } else if (t > target) 39 | /* 40 | Partial Match: back up to the beginning of that partial 41 | match so we can try again from the following character. 42 | (i.e., ensure that our normal 's++' leaves us in the right position) 43 | */ 44 | s -= (t - target); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /13/13.5-sum.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | if (argc < 3) { 7 | fprintf(stderr, "Use more than 1 argument\n"); 8 | } 9 | 10 | int sum = 0; 11 | for (int i = 1; i < argc; i++) sum += atoi(argv[i]); 12 | /* for (char **i = &argv[1]; i < argv + argc; i++) sum += atoi(*i); */ 13 | 14 | printf("Total: %d\n", sum); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /13/13.5.11-str-cmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int str_cmp(char *s, char *t); 4 | 5 | void print_comparison(char *a, char *b) 6 | { 7 | int result = str_cmp(a, b); 8 | printf("%s == %s? %d:(%d)\n", a, b, (result == 0), result); 9 | } 10 | int main(void) 11 | { 12 | char *a = "abc", *b = "ABC", *c = "0123", *d = "abcd"; 13 | 14 | print_comparison(a, b); 15 | print_comparison(a, "abc"); 16 | print_comparison(b, a); 17 | print_comparison(a, c); 18 | print_comparison(a, d); 19 | print_comparison(d, c); 20 | print_comparison(c, d); 21 | return 0; 22 | } 23 | 24 | int str_cmp(char *s, char *t) 25 | { 26 | for (;*s == *t; s++, t++) 27 | if (!*s) 28 | return 0; 29 | 30 | return *s - *t; 31 | } 32 | -------------------------------------------------------------------------------- /13/13.5.12-get-extension.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void get_extension(char *file_name, char *extension) 5 | { 6 | 7 | char *dot; 8 | extension[0] = '\0'; 9 | 10 | if ((dot = strrchr(file_name, '.'))) 11 | strcpy(extension, ++dot); 12 | } 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | if (argc != 2) { 17 | fprintf(stderr, "Usage: %s file_name.ext\n", argv[0]); 18 | return 1; 19 | } 20 | char ext[16]; 21 | get_extension(argv[1], ext); 22 | printf("File Extension: '%s'\n", ext); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /13/13.5.13-index-url.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void build_index_url(const char *domain, char *index_url) 5 | { 6 | strcpy(index_url, "http://www."); 7 | strcat(index_url, domain); 8 | strcat(index_url, "/index.html"); 9 | } 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | if (argc != 2) { 14 | fprintf(stderr, "Usage: %s \n", argv[0]); 15 | return 1; 16 | } 17 | 18 | char url[255]; 19 | 20 | build_index_url(argv[1], url); 21 | 22 | printf("%s\n", url); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /13/13.6-planet.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* planet.c (Chapter 13, page 304) */ 11 | /* Checks planet names */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #define NUM_PLANETS 9 18 | 19 | char *capitalize(char *s); 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | char *planets[] = {"Mercury", "Venus", "Earth", 24 | "Mars", "Jupiter", "Saturn", 25 | "Uranus", "Neptune", "Pluto"}; 26 | int i, j; 27 | 28 | for (i = 1; i < argc; i++) { 29 | for (j = 0; j < NUM_PLANETS; j++) 30 | if (strcmp(capitalize(argv[i]), planets[j]) == 0) { 31 | printf("%s is planet %d\n", argv[i], j + 1); 32 | break; 33 | } 34 | if (j == NUM_PLANETS) 35 | printf("%s is not a planet\n", argv[i]); 36 | } 37 | 38 | return 0; 39 | } 40 | char *capitalize(char *s) 41 | { 42 | char *word = s; 43 | *s = toupper(*s); 44 | s++; 45 | while (*s) { 46 | *s = tolower(*s); 47 | s++; 48 | } 49 | return word; 50 | } 51 | -------------------------------------------------------------------------------- /13/13.6.16-count-spaces.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | int count_spaces(const char *s) 5 | { 6 | int spaces = 0; 7 | 8 | while (*s) 9 | if (*s++ == ' ') 10 | spaces++; 11 | 12 | return spaces; 13 | } 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | if (argc != 2) { 18 | fprintf(stderr, "Usage: %s \n", argv[0]); 19 | return 1; 20 | } 21 | 22 | printf("Spaces: %d\n", count_spaces(argv[1])); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /13/13.6.17-test-extension.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | bool test_extension(const char *filename, const char *ext) 8 | { 9 | int f_size = strlen(filename); 10 | int e_size = strlen(ext); 11 | if (e_size >= f_size) 12 | return false; 13 | 14 | /* where the extension would start in the file name */ 15 | const char *p = (filename + f_size) - e_size; 16 | while (*p) 17 | /* "*p++": get the value, then increment the pointer */ 18 | if (toupper(*p++) != toupper(*ext++)) 19 | return false; 20 | 21 | return true; 22 | } 23 | 24 | int main(int argc, char *argv[]) 25 | { 26 | if (argc != 3) { 27 | fprintf(stderr, "Usage: %s file_name ext\n", argv[0]); 28 | return 1; 29 | } 30 | 31 | printf("%d\n", test_extension(argv[1], argv[2])); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /13/13.6.18-remove-filename.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void remove_filename(char *url) 4 | { 5 | char *p = NULL; 6 | while (*url) { 7 | if (*url == '/') 8 | p = url; 9 | url++; 10 | } 11 | 12 | /* if any slashes were found, this will point to the last of them */ 13 | if (*p) 14 | *p = '\0'; 15 | } 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | if (argc != 2) { 20 | fprintf(stderr, "Usage: %s \n", argv[0]); 21 | return 1; 22 | } 23 | 24 | remove_filename(argv[1]); 25 | printf("%s\n", argv[1]); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /13/13.7-spell-number.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int toi(char digit) 4 | { 5 | return (int) digit - '0'; 6 | } 7 | char *get_ones(char digit) 8 | { 9 | char *ones[] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; 10 | return ones[toi(digit) - 1]; 11 | } 12 | char *get_tens(char digit) 13 | { 14 | char *tens[] = {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}; 15 | return tens[toi(digit) - 2]; 16 | } 17 | char *get_teens(char digit) 18 | { 19 | char *teens[] = {"ten", "eleven", "twelve", "thirteen", "fourteen", 20 | "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}; 21 | return teens[toi(digit)]; 22 | } 23 | int main(void) 24 | { 25 | char ones, tens; 26 | printf("Enter a two-digit number: "); 27 | scanf("%1c%1c", &tens, &ones); 28 | 29 | if (tens == '1') 30 | printf("%s\n", get_teens(ones)); 31 | else if (ones == '0') 32 | printf("%s\n", get_tens(tens)); 33 | else 34 | printf("%s-%s\n", get_tens(tens), get_ones(ones)); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /13/13.8-scrabble.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int compute_scrabble_value(const char *word); 5 | 6 | int main(void) 7 | { 8 | char word[128]; 9 | 10 | printf("Enter a word: "); 11 | 12 | scanf("%127s", word); 13 | 14 | printf("Scrabble Value: %d\n", compute_scrabble_value(word)); 15 | return 0; 16 | } 17 | int compute_scrabble_value(const char *word) 18 | { 19 | int scrabble_weights[26] = { 20 | 1, //A 21 | 3, //B 22 | 3, //C 23 | 2, //D 24 | 1, //E 25 | 4, //F 26 | 2, //G 27 | 4, //H 28 | 1, //I 29 | 8, //J 30 | 5, //K 31 | 1, //L 32 | 3, //M 33 | 1, //N 34 | 1, //0 35 | 3, //P 36 | 10,//Q 37 | 1, //R 38 | 1, //S 39 | 1, //T 40 | 1, //U 41 | 4, //V 42 | 4, //W 43 | 8, //X 44 | 4, //Y 45 | 10 //Z 46 | }; 47 | 48 | char ch; 49 | int sum = 0; 50 | 51 | while (*word) { 52 | ch = toupper(*word++); 53 | if (ch >= 'A' && ch <= 'Z') 54 | sum += scrabble_weights[ch - 'A']; 55 | } 56 | 57 | return sum; 58 | } 59 | -------------------------------------------------------------------------------- /13/13.9-vowel-count.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SIZE 1024 5 | 6 | int count_vowels(const char *sentence); 7 | 8 | int main(void) 9 | { 10 | char s[SIZE + 1]; 11 | 12 | printf("Enter a sentence: "); 13 | fgets(s, sizeof(s), stdin); 14 | 15 | printf("Vowel count: %d\n", count_vowels(s)); 16 | return 0; 17 | } 18 | int count_vowels(const char *sentence) 19 | { 20 | int sum = 0; 21 | while (*sentence) { 22 | switch(tolower(*sentence++)) { 23 | case 'a': 24 | case 'e': 25 | case 'i': 26 | case 'o': 27 | case 'u': 28 | sum++; 29 | break; 30 | } 31 | } 32 | 33 | return sum; 34 | } 35 | -------------------------------------------------------------------------------- /14/14.3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | #define CUBE(x) ((x) * (x) * (x)) 6 | #define NMOD_4(n) ((int)(n) % 4) 7 | #define XY(x,y) ( (x)*(y) < 100 ? (x)*(y) : 0 ) 8 | #define NELEMS(a) ((int) (sizeof(a) / sizeof(a[0]))) 9 | #define AVG(x,y) ((x)+(y)/2) 10 | #define AREA(x,y) ((x)*(y)) 11 | #define TOUPPER(c) ('a' <= (c) && (c) <= 'z' ? (c)-'a'+'A':(c)) 12 | #define DISP(f,x) printf(#f "(%g) = %g\n", (x), f(x)) 13 | #define NEWLINE printf("\n") 14 | 15 | double square(double x) 16 | { 17 | return x * x; 18 | } 19 | void test_disp(void) 20 | { 21 | NEWLINE; 22 | DISP(square, 3.0); 23 | 24 | NEWLINE; 25 | } 26 | void test_toupper(void) 27 | { 28 | puts(""); 29 | char s[5]; 30 | strcpy(s, "abcd"); 31 | int i = 0; 32 | putchar(TOUPPER(s[++i])); 33 | 34 | puts(""); 35 | 36 | strcpy(s, "0123"); 37 | i = 0; 38 | putchar(TOUPPER(s[++i])); 39 | 40 | puts(""); 41 | } 42 | void test_nelms_macro(void) 43 | { 44 | int ai[1234] = {0}; 45 | float af[2234] = {0.0}; 46 | double ad[3234] = {0.0}; 47 | char ac[4234] = {'\0'}; 48 | 49 | printf("\nTesting Arrays\n"); 50 | printf("%d int\n", NELEMS(ai)); 51 | printf("%d float\n", NELEMS(af)); 52 | printf("%d double\n", NELEMS(ad)); 53 | printf("%d char\n", NELEMS(ac)); 54 | } 55 | 56 | int main(void) 57 | { 58 | int y = 2; 59 | 60 | printf("%.3f, %d\n", CUBE(1.2), CUBE(y + 3)); 61 | 62 | printf("%d, %d\n", NMOD_4(7.9), NMOD_4(17)); 63 | 64 | printf("%.3f\n", XY(14.0,.3f)); 65 | 66 | test_nelms_macro(); 67 | 68 | test_toupper(); 69 | 70 | test_disp(); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /15/15.1.justify.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* justify.c (Chapter 15, page 363) */ 11 | /* Formats a file of text */ 12 | 13 | #include 14 | #include "line.h" 15 | #include "word.h" 16 | 17 | #define MAX_WORD_LEN 28 18 | 19 | int main(void) 20 | { 21 | char word[MAX_WORD_LEN+2]; 22 | int word_len; 23 | 24 | clear_line(); 25 | for (;;) { 26 | word_len = read_word(word, MAX_WORD_LEN+1); 27 | if (word_len == 0) { 28 | flush_line(); 29 | return 0; 30 | } 31 | if (word_len + 1 > space_remaining()) { 32 | write_line(); 33 | clear_line(); 34 | } 35 | add_word(word); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /15/makefile: -------------------------------------------------------------------------------- 1 | PREFIX = ../ 2 | 3 | include $(PREFIX)make/env.mk 4 | 5 | COMPILE = $(CC) -c $(CFLAGS) $< 6 | LINK = $(LD) $^ -o $@ 7 | 8 | all: 15.1.justify 15.3.qsort 15.5.RPN-calculator 9 | 10 | 15.1.justify: 15.1.justify.o $(LIBS)/line.o $(LIBS)/word.o 11 | $(LINK) 12 | 13 | 15.1.justify.o: 15.1.justify.c $(INCS)/line.h $(INCS)/word.h 14 | $(COMPILE) 15 | 16 | 15.3.qsort: 15.3.qsort.o quicksort.o 17 | $(LINK) 18 | 19 | 15.3.qsort.o: 15.3.qsort.c quicksort.h 20 | $(COMPILE) 21 | 22 | quicksort.o: %.o : %.c %.h 23 | $(COMPILE) 24 | 25 | 15.5.RPN-calculator: 15.5.RPN-calculator.o $(LIBS)/tokenize.o stack.o 26 | $(LINK) 27 | 28 | 15.5.RPN-calculator.o: 15.5.RPN-calculator.c $(INCS)/tokenize.h stack.h 29 | $(COMPILE) 30 | 31 | stack.o tokenize.o: %.o : %.c %.h 32 | $(COMPILE) 33 | 34 | include $(PREFIX)make/clean.mk 35 | include $(LIBS)/makefile 36 | -------------------------------------------------------------------------------- /15/quicksort.c: -------------------------------------------------------------------------------- 1 | #include "quicksort.h" 2 | 3 | void quicksort(int *low, int *high) 4 | { 5 | int *middle; 6 | 7 | if (low >= high) return; 8 | middle = split(low, high); 9 | quicksort(low, middle - 1); 10 | quicksort(middle + 1, high); 11 | } 12 | 13 | int *split(int *low, int *high) 14 | { 15 | int part_element = *low; 16 | 17 | for (;;) { 18 | while (low < high && part_element <= *high) 19 | high--; 20 | if (low >= high) break; 21 | *low = *high; 22 | low++; 23 | 24 | while (low < high && *low <= part_element) 25 | low++; 26 | if (low >= high) break; 27 | *high = *low; 28 | high--; 29 | } 30 | 31 | *high = part_element; 32 | return high; 33 | } 34 | -------------------------------------------------------------------------------- /15/quicksort.h: -------------------------------------------------------------------------------- 1 | #ifndef QUICKSORT_H 2 | #define QUICKSORT_H 3 | 4 | void quicksort(int *low, int *high); 5 | int *split(int *low, int *high); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /15/stack.c: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | 3 | #define STACK_SIZE 100 4 | 5 | int stack[STACK_SIZE]; 6 | int top = 0; 7 | 8 | void empty_stack(void) 9 | { 10 | top = 0; 11 | } 12 | bool is_empty(void) 13 | { 14 | return top == 0; 15 | } 16 | bool is_full(void) 17 | { 18 | return top == STACK_SIZE; 19 | } 20 | void push(int operand) 21 | { 22 | if (is_full()) { 23 | exit_stack_overflow(); 24 | return; 25 | } 26 | stack[top++] = operand; 27 | } 28 | int pop(void) 29 | { 30 | if (is_empty()) { 31 | exit_stack_underflow(); 32 | return 0; 33 | } 34 | return stack[--top]; 35 | } 36 | void exit_stack_overflow(void) 37 | { 38 | fprintf(stderr, "Stack Overflow.\n"); 39 | exit(EXIT_FAILURE); 40 | } 41 | void exit_stack_underflow(void) 42 | { 43 | fprintf(stderr, "Stack Underflow\n"); 44 | exit(EXIT_FAILURE); 45 | } 46 | -------------------------------------------------------------------------------- /15/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | extern int stack[]; 9 | extern int top; 10 | 11 | void empty_stack(void); 12 | bool is_empty(void); 13 | bool is_full(void); 14 | void push(int operand); 15 | int pop(void); 16 | void exit_stack_overflow(void); 17 | void exit_stack_underflow(void); 18 | #endif 19 | -------------------------------------------------------------------------------- /16/16.1.4.type-complex.c: -------------------------------------------------------------------------------- 1 | #if 1 2 | typedef struct { double imaginary; double real; } complex; 3 | complex make_complex(double i, double r) 4 | { 5 | return (complex) { .imaginary = i, .real = r }; 6 | } 7 | complex add_complex(complex a, complex b) 8 | { 9 | return (complex) { .imaginary = a.imaginary + b.imaginary, .real = a.real + b.real}; 10 | } 11 | #endif 12 | int main(void) 13 | { 14 | /* complex c1, c2 = { 2.05, 1001}; */ 15 | /* complex c3 = make_complex(1.31, 932); */ 16 | /* complex c4 = add_complex(c2, c3); */ 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /16/16.1.5-6.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "time_helper.h" 4 | 5 | typedef struct 6 | { 7 | int month, day, year; 8 | } date; 9 | int day_of_year(date d) 10 | { 11 | int eom[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 12 | int i, days = 0; 13 | 14 | /*leap year?*/ 15 | if ((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0) 16 | eom[2] = 29; 17 | 18 | /*accumulate all the days in each preceding month*/ 19 | for (i = 0; i < d.month; i++) 20 | days += eom[i]; 21 | 22 | return days + d.day; 23 | } 24 | void print_date(date d) 25 | { 26 | printf("%d/%d/%d\n", d.month, d.day, d.year); 27 | } 28 | int compare_dates(date d1, date d2) 29 | { 30 | if (d1.year < d2.year) 31 | return -1; 32 | else if (d1.year > d2.year) 33 | return 1; 34 | else { 35 | int day1 = day_of_year(d1); 36 | int day2 = day_of_year(d2); 37 | if (day1 < day2) 38 | return -1; 39 | if (day1 > day2) 40 | return 1; 41 | } 42 | return 0; 43 | } 44 | 45 | date random_date() 46 | { 47 | struct tm *t = random_tm(); 48 | return (date) {t->tm_mon + 1, t->tm_mday, t->tm_year + 1900}; 49 | } 50 | int main() 51 | { 52 | srand((unsigned) time(NULL)); 53 | 54 | date d1 = random_date(); 55 | date d2 = random_date(); 56 | print_date(d1); 57 | print_date(d2); 58 | printf("%d\n", compare_dates(d1, d2)); 59 | d1.year = d2.year; 60 | print_date(d1); 61 | print_date(d2); 62 | printf("%d\n", compare_dates(d1, d2)); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /16/16.1.9.color.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct { 5 | int red; 6 | int green; 7 | int blue; 8 | } color; 9 | 10 | color make_color(int red, int green, int blue); 11 | int set_color(int c); 12 | int get_red(color c); 13 | bool colors_equal(color color1, color color2); 14 | color brighter(color c); 15 | color darker(color c); 16 | 17 | int main(void) 18 | { 19 | 20 | return 0; 21 | } 22 | color make_color(int red, int green, int blue) 23 | { 24 | return (color) {set_color(red), 25 | set_color(green), 26 | set_color(blue)}; 27 | } 28 | int get_red(color c) 29 | { 30 | return c.red; 31 | } 32 | bool colors_equal(color color1, color color2) 33 | { 34 | return (color1.red == color2.red && 35 | color1.green == color2.green && 36 | color1.blue == color2.blue); 37 | } 38 | int brighten(int c) 39 | { 40 | if (c < 3) c = 3; 41 | c = (int) ( (float)c / 0.7f); 42 | return c > 255 ? 255 : c; 43 | } 44 | color brighter(color c) 45 | { 46 | if (colors_equal(c, (color) {0,0,0})) 47 | return make_color(3,3,3); 48 | 49 | c.red = brighten(c.red); 50 | c.green = brighten(c.green); 51 | c.blue = brighten(c.blue); 52 | 53 | return c; 54 | } 55 | int darken(int c) 56 | { 57 | return (int) ((float) c * 0.7f); 58 | } 59 | color darker(color c) 60 | { 61 | c.red = darken(c.red); 62 | c.green = darken(c.green); 63 | c.blue = darken(c.blue); 64 | 65 | return c; 66 | } 67 | int set_color(int c) 68 | { 69 | if (c < 0) return 0; 70 | if (c > 255) return 255; 71 | return c; 72 | } 73 | -------------------------------------------------------------------------------- /16/16.1.country-codes.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct { 4 | char *country; 5 | int code; 6 | } dialing_code; 7 | 8 | const dialing_code country_codes[] = { 9 | {"Argentina", 54}, {"Bangladesh", 880}, 10 | {"Brazil", 55}, {"Burma (Myanmar)", 95}, 11 | {"China", 86}, {"United States", 1} 12 | }; 13 | 14 | char *find_country(int code) 15 | { 16 | static int size = (int) (sizeof(country_codes) / sizeof(country_codes[0])); 17 | for (int i = 0; i < size; i++) { 18 | if (country_codes[i].code == code) 19 | return country_codes[i].country; 20 | } 21 | return ""; 22 | } 23 | #ifdef TEST 24 | #include "test_runner.h" 25 | 26 | int find_code_test(void) 27 | { 28 | _assert(strcmp(find_country(54), "Argentina") == 0); 29 | _assert(strcmp(find_country(55), "Argentina") != 0); 30 | _assert(strcmp(find_country(55), "Brazil") == 0); 31 | return 0; 32 | } 33 | 34 | int find_nothing_test(void) 35 | { 36 | _assert(strcmp(find_country(1000), "") == 0); 37 | return 0; 38 | } 39 | 40 | int all_tests(void) 41 | { 42 | _run(find_code_test); 43 | _run(find_nothing_test); 44 | 45 | return 0; 46 | } 47 | #else 48 | #include 49 | #include "error.h" 50 | 51 | int main(int argc, char *argv[]) 52 | { 53 | if (argc < 2) 54 | invocation_error(argv[0], ""); 55 | 56 | int code = atoi(argv[1]); 57 | 58 | char *country = find_country(code); 59 | 60 | if (strlen(country) > 0) 61 | printf("%s:\t %d\n", country, code); 62 | else 63 | printf("Error: no country found for code '%d'\n", code); 64 | 65 | return 0; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /16/16.1.exercises.c: -------------------------------------------------------------------------------- 1 | #if 0 2 | void ex_1(void) 3 | { 4 | 5 | struct { int x, y; } x; 6 | struct { int x, y; } y; 7 | 8 | x.x = 1; 9 | x.y = 2; 10 | 11 | y.x = 10; 12 | y.y = 20; 13 | } 14 | 15 | void ex_2a(void) 16 | { 17 | struct { 18 | double imaginary; 19 | double real; 20 | } c1, c2, c3; 21 | } 22 | 23 | void ex_2b(void) 24 | { 25 | struct { double imaginary; double real; } c1 = {0.0, 1.0}; 26 | struct { double imaginary; double real; } c2 = {1.0, 0.0}; 27 | struct { double imaginary; double real; } c3; 28 | 29 | } 30 | 31 | void ex_2cd(void) 32 | { 33 | struct { double imaginary; double real; } c1 = {0.0, 1.0}; 34 | struct { double imaginary; double real; } c2 = {1.0, 0.0}; 35 | struct { double imaginary; double real; } c3; 36 | 37 | c3.imaginary = c1.imaginary + c2.imaginary; 38 | c3.real = c1.real + c2.imaginary; 39 | c1.imaginary = c2.imaginary; 40 | c1.real = c2.real; 41 | } 42 | 43 | struct complex { double imaginary; double real; }; 44 | struct complex make_complex(double i, double r) 45 | { 46 | return (struct complex) { .imaginary = i, .real = r }; 47 | } 48 | struct complex add_complex(struct complex a, struct complex b) 49 | { 50 | return (struct complex) { .imaginary = a.imaginary + b.imaginary, .real = a.real + b.real}; 51 | } 52 | void ex_3(void) 53 | { 54 | struct complex c1, c2 = { 2.05, 1001}; 55 | struct complex c3 = make_complex(1.31, 932); 56 | struct complex c4 = add_complex(c2, c3); 57 | } 58 | 59 | #endif 60 | int main(void) 61 | { 62 | 63 | /* ex_1(); */ 64 | /* ex_2a(); */ 65 | /* ex_2b(); */ 66 | /* ex_2cd(); */ 67 | /* ex_3(); */ 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /16/16.5.20.directions.c: -------------------------------------------------------------------------------- 1 | #include "test_runner.h" 2 | 3 | typedef enum {NORTH, SOUTH, EAST, WEST} direction; 4 | typedef struct {int x; int y; } point; 5 | 6 | point move(point p, direction d) 7 | { 8 | switch(d) { 9 | case NORTH: 10 | p.y++; 11 | break; 12 | case SOUTH: 13 | p.y--; 14 | break; 15 | case EAST: 16 | p.x--; 17 | break; 18 | case WEST: 19 | p.x++; 20 | break; 21 | } 22 | return p; 23 | } 24 | 25 | point center(void) { return (point) {0, 0}; } 26 | 27 | int move_south_test(void) 28 | { 29 | point moved = move(center(), SOUTH); 30 | _assert(moved.x == 0); 31 | _assert(moved.y == -1); 32 | 33 | return 0; 34 | } 35 | int move_east_test(void) 36 | { 37 | point moved = move(center(), EAST); 38 | _assert(moved.x == -1); 39 | _assert(moved.y == 0); 40 | return 0; 41 | } 42 | int move_west_test(void) 43 | { 44 | point moved = move(center(), WEST); 45 | _assert(moved.x == 1); 46 | _assert(moved.y == 0); 47 | return 0; 48 | } 49 | int move_north_test(void) 50 | { 51 | point moved = move(center(), NORTH); 52 | _assert(moved.x == 0); 53 | _assert(moved.y == 1); 54 | return 0; 55 | } 56 | int move_northwest_test(void) 57 | { 58 | point moved = move(center(), NORTH); 59 | moved = move(moved, WEST); 60 | _assert(moved.x == 1); 61 | _assert(moved.y == 1); 62 | return 0; 63 | } 64 | int all_tests(void) 65 | { 66 | _run(move_south_test); 67 | _run(move_east_test); 68 | _run(move_west_test); 69 | _run(move_north_test); 70 | _run(move_northwest_test); 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /16/makefile: -------------------------------------------------------------------------------- 1 | PREFIX = ../ 2 | 3 | include $(PREFIX)make/env.mk 4 | EXCLUDE = ./16.1.5-6.c ./16.1.7.fraction.c ./16.1.country-codes.c ./16.inventory.c 5 | include $(PREFIX)make/generic.mk 6 | 7 | all: 16.1.5-6 $(EXECUTABLES) 16.1.7.fraction ./16.1.country-codes ./16.inventory 8 | 9 | COMPILE = $(CC) -c $(CFLAGS) $< 10 | LINK = $(LD) $^ -o $@ 11 | 12 | 13 | ############################################################################################################################################# 14 | # Same as 17/17.3-inventory, except we use lib/parts-array.c instead of lib/parts-list.c 15 | ############################################################################################################################################# 16 | 16.inventory: 16.inventory.o $(LIBS)/parts.o $(LIBS)/parts-array.o $(LIBS)/inventory-view.o $(LIBS)/part.o $(LIBS)/readline.o $(LIBS)/error.o 17 | $(LINK) 18 | 19 | 16.inventory.o: 16.inventory.c $(INCS)/parts.h $(INCS)/inventory-view.h $(INCS)/part.h $(INCS)/part-type.h $(INCS)/readline.h $(INCS)/error.h 20 | $(COMPILE) 21 | 22 | 16.1.country-codes: 16.1.country-codes.o $(LIBS)/error.o 23 | $(LINK) 24 | 25 | 16.1.country-codes.o: 16.1.country-codes.c $(INCS)/error.h 26 | $(COMPILE) 27 | 28 | 16.1.7.fraction: 16.1.7.fraction.o $(LIBS)/error.o 29 | $(LINK) 30 | 31 | 16.1.7.fraction.o: 16.1.7.fraction.c $(INCS)/error.h 32 | $(COMPILE) 33 | 34 | 16.1.5-6: 16.1.5-6.o $(LIBS)/time_helper.o 35 | $(LINK) 36 | 37 | 16.1.5-6.o: 16.1.5-6.c $(INCS)/time_helper.h 38 | $(COMPILE) 39 | 40 | include $(PREFIX)make/clean.mk 41 | include $(LIBS)/makefile 42 | -------------------------------------------------------------------------------- /17/17.1.1-malloc-or-die.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void *malloc_or_die(size_t size) 8 | { 9 | void *p; 10 | 11 | if ((p = malloc(size))== NULL) { 12 | fprintf(stderr, "Out of memory: %s %d (%s)\n", __FILE__, __LINE__, __func__); 13 | exit(1); 14 | } 15 | 16 | return p; 17 | } 18 | int main(void) 19 | { 20 | 21 | char *s; 22 | for (int i = 0; i < 20000; i++) 23 | { 24 | s = malloc_or_die(INT_MAX); 25 | if ( i % 8 == 0) 26 | printf("%s\n", s); 27 | printf("%p\t",s); 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /17/17.2.2-duplicate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *duplicate1(char *s) 6 | { 7 | char *p; 8 | if ((p = malloc(strlen(s) + 1)) == NULL) 9 | return NULL; 10 | strcpy(p,s); 11 | return p; 12 | } 13 | char *duplicate2(char *s) 14 | { 15 | char *target, *p; 16 | if ((p = malloc(strlen(s) + 1)) == NULL) 17 | return NULL; 18 | target = p; 19 | while (( *p++ = *s++ )); 20 | return target; 21 | } 22 | char *duplicate_stupidly(char *s) 23 | { 24 | if (!*s) 25 | return ""; 26 | 27 | /* initialize for the first call to realloc, */ 28 | /* which acts like malloc if given NULL */ 29 | char *p = NULL; 30 | 31 | /* Don't get the size up front, "just" reallocate 32 | * our block every byte until we're not null */ 33 | int i = 0; 34 | do { 35 | if ((p = realloc(p, i + 1)) == NULL) 36 | return NULL; 37 | } while ((p[i++] = *s++)); 38 | 39 | return p; 40 | } 41 | int main(void) 42 | { 43 | char *t, *s = "Bifurcate!\n And Do It Well, you bastards!\n"; 44 | 45 | /* t = duplicate1(s); */ 46 | /* t = duplicate2(s); */ 47 | t = duplicate_stupidly(s); 48 | printf("%p: %s\n", &t, t); 49 | free(t); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /17/17.3.3-create-array.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int *create_array(int n, int initial_value) 6 | { 7 | int *a; 8 | a = malloc(n * sizeof(int)); 9 | if (!a) 10 | return NULL; 11 | 12 | for (int i = 0; i < n; i++) 13 | a[i] = initial_value; 14 | 15 | return a; 16 | } 17 | #define SIZE 923 18 | int main(void) 19 | { 20 | int *A = create_array(SIZE, INT_MAX); 21 | 22 | for (int i = 0; i < SIZE; i++) 23 | printf("%d:%d\n", i, A[i]); 24 | 25 | puts(""); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /17/17.5-sort-words.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "readline.h" 4 | #include "error.h" 5 | #include 6 | 7 | #define MAX_WORDS 1024 8 | #define WORD_LEN 28 9 | int compare_words(const void *a, const void *b) 10 | { 11 | char **string_a = (char **)a; 12 | char **string_b = (char **)b; 13 | 14 | return strcmp(*string_a, *string_b); 15 | } 16 | int main(void) 17 | { 18 | char input[WORD_LEN + 1]; 19 | char *words[MAX_WORDS]; 20 | int word_count = 0; 21 | 22 | for(;;) { 23 | if (word_count == MAX_WORDS) { 24 | printf("Word max %d reached.", word_count); 25 | break; 26 | } 27 | 28 | printf("Word? "); 29 | read_line(input, WORD_LEN); 30 | if (input[0] == '0') 31 | break; 32 | 33 | /* on my 64 bit machine, malloc will probably allocate nearly an MB anyway! */ 34 | words[word_count] = malloc(strlen(input) + 1); 35 | if (!words[word_count]) 36 | memory_error(__FILE__, __LINE__, __func__); 37 | 38 | strcpy(words[word_count], input); 39 | word_count++; 40 | } 41 | 42 | qsort(words, word_count, sizeof(char *), compare_words); 43 | 44 | for (int i = 0; i < word_count; i++) { 45 | printf("%s\n", words[i]); 46 | free(words[i]); 47 | } 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /17/17.5.13-bad-insert.lst: -------------------------------------------------------------------------------- 1 | #if 0 2 | /* 3 | Case 1: new_node->value < head->value (beginning) 4 | 5 | assign address of structure pointed to by head to new_node->next 6 | assign address of structure pointed to by new_node to head 7 | return head 8 | 9 | i.e., 10 | new_node->next = head; 11 | head = new_node; 12 | return head; 13 | 14 | Cases 2 : new_node->value <= last->value (middle) 15 | and 3: new_node->value > last->value (end) 16 | assign address of structure pointed to by head to current and NULL to previous 17 | while current is != NULL and current->value <= new_node->value 18 | advance current and previous, i.e: 19 | assign address of structure pointed to by current to previous (prev = cur;) 20 | assign address of structure pointed to by current->next to current (cur = cur->next;) 21 | 22 | assign address of structure pointed to by new_node to previous->next 23 | i.e. (prev->next = new_node;) 24 | works for middle and end 25 | 26 | if current != NULL (because current->next was NOT null on last iteration of the loop, i.e, a middle case) 27 | assign address of structure pointed to by current to new_node->next (new_node->next = current;) 28 | 29 | 30 | return head 31 | */ 32 | #endif 33 | -------------------------------------------------------------------------------- /17/17.5.4-dynamic-rectangle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | struct point { int x, y; }; 7 | struct rectangle { struct point upper_left, lower_right; }; 8 | struct rectangle *p; 9 | 10 | p = malloc(sizeof(struct rectangle)); 11 | p->upper_left = (struct point){10,25}; 12 | p->lower_right = (struct point){20,15}; 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /17/makefile: -------------------------------------------------------------------------------- 1 | PREFIX = ../ 2 | 3 | include $(PREFIX)make/env.mk 4 | EXCLUDE = ./17.3-inventory.c ./17.4-line.c ./17.5-sort-words.c 5 | include $(PREFIX)make/generic.mk 6 | 7 | all: $(EXECUTABLES) ./17.3-inventory ./17.4-justify ./17.5-sort-words 8 | 9 | COMPILE = $(CC) -c $(CFLAGS) $< 10 | LINK = $(LD) $^ -o $@ 11 | 12 | 17.5-sort-words: 17.5-sort-words.o $(LIBS)/readline.o $(LIBS)/error.o 13 | $(LINK) 14 | 15 | 17.5-sort-words.o: 17.5-sort-words.c $(INCS)/readline.h $(INCS)/error.h 16 | $(COMPILE) 17 | 18 | 17.4-justify: 17.4-justify.o 17.4-line.o $(LIBS)/word.o 19 | $(LINK) 20 | 21 | 15 = $(PREFIX)15/ 22 | 17.4-justify.o: $(15)15.1.justify.c $(INCS)/line.h $(INCS)/word.h 23 | $(COMPILE) -o $@ 24 | 25 | 17.4-line.o: 17.4-line.c $(INCS)/line.h 26 | $(COMPILE) 27 | 28 | ################################################################################################################################################ 29 | # Same as 16/16.inventory, except we use lib/parts-list.c instead of lib/parts-array.c 30 | ################################################################################################################################################ 31 | 17.3-inventory: 17.3-inventory.o $(LIBS)/parts.o $(LIBS)/parts-list.o $(LIBS)/inventory-view.o $(LIBS)/part.o $(LIBS)/readline.o $(LIBS)/error.o 32 | $(LINK) 33 | 34 | 16 = $(PREFIX)16/ 35 | 17.3-inventory.o: $(16)16.inventory.c $(INCS)/parts.h $(INCS)/inventory-view.h $(INCS)/part.h $(INCS)/part-type.h $(INCS)/readline.h $(INCS)/error.h 36 | $(COMPILE) -o $@ 37 | 38 | include $(PREFIX)make/clean.mk 39 | include $(LIBS)/makefile 40 | -------------------------------------------------------------------------------- /18/18.2.h: -------------------------------------------------------------------------------- 1 | /* 18.2.3 */ 2 | extern float a; 3 | 4 | void f(register double b) 5 | { 6 | 7 | static int c; 8 | auto char d; 9 | } 10 | 11 | /* 12 | var storage duration scope linkage 13 | __________________________________________________ 14 | a static file external 15 | b automatic block none 16 | c static block none 17 | d automatic block none 18 | 19 | */ 20 | 21 | 22 | /* 18.2.4 */ 23 | 24 | inf f(int i) 25 | { 26 | static int j = 0; 27 | return i * j++; 28 | } 29 | 30 | /* 31 | first call, f(10) == 0 32 | sixth call, f(10) == 50 33 | */ 34 | 35 | /* 18.2.6 */ 36 | 37 | void print_error(const char *message) 38 | { 39 | /* int n = 1; needed to static */ 40 | static int n = 1; 41 | printf("Error %d: %s\n", n++, message); 42 | } 43 | -------------------------------------------------------------------------------- /19/19.1-nester-tester.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../src/stackADT.h" 4 | 5 | void exit_incorrect_nesting(Stack s) 6 | { 7 | printf("Nesting is NOT correct\n"); 8 | destroy(s); 9 | exit(EXIT_SUCCESS); 10 | } 11 | int main(void) 12 | { 13 | int ch; 14 | Stack s = create(); 15 | 16 | printf("Enter parentheses and/or braces: "); 17 | 18 | while ((ch = getchar()) != '\n') { 19 | switch(ch) { 20 | case '(': 21 | case '{': 22 | push(s, ch); 23 | break; 24 | case ')': 25 | if (is_empty(s) || pop(s) != '(') 26 | exit_incorrect_nesting(s); 27 | break; 28 | case '}' : 29 | if (is_empty(s) || pop(s) != '{') 30 | exit_incorrect_nesting(s); 31 | break; 32 | } 33 | } 34 | 35 | if (is_empty(s)) 36 | printf("Nesting is correct\n"); 37 | else 38 | exit_incorrect_nesting(s); 39 | 40 | destroy(s); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /19/19.3a.bounded-queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "bounded-queue.h" 4 | 5 | int main(void) 6 | { 7 | Queue q = create_queue(37); 8 | insert_item(q, 2); 9 | assert(remove_item(q) == 2); 10 | assert(is_empty(q) == true); 11 | 12 | printf("This should exit with a failure.\n\n"); 13 | /* remove_item(q); */ 14 | front(q); 15 | rear(q); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /19/19.5-queue-client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "queue.h" 7 | 8 | int main(void) 9 | { 10 | Queue q1, q2; 11 | int n; 12 | 13 | srand((unsigned) time(NULL)); 14 | 15 | q1 = create_queue(); 16 | q2 = create_queue(); 17 | 18 | insert_item(q1, 1); 19 | insert_item(q1, 2); 20 | 21 | n = remove_item(q1); 22 | printf("Removed %d from q1\n", n); 23 | insert_item(q2, n); 24 | n = remove_item(q1); 25 | printf("Removed %d from q1\n", n); 26 | insert_item(q2, n); 27 | 28 | assert(is_empty(q1)); 29 | assert(!is_empty(q2)); 30 | 31 | for (int i = 0; i < 1024; i++) 32 | insert_item(q1, rand() % INT_MAX); 33 | 34 | while (!is_empty(q1)) 35 | printf("rear: %d, removed from front: %d\n", rear(q1), remove_item(q1)); 36 | while (!is_empty(q2)) 37 | printf("Removed %d from q2\n", remove_item(q2)); 38 | 39 | insert_item(q2, 3); 40 | clear(q2); 41 | if (is_empty(q2)) 42 | printf("q2 is empty\n"); 43 | else 44 | printf("q2 is not empty\n"); 45 | 46 | destroy(q1); 47 | destroy(q2); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /19/makefile: -------------------------------------------------------------------------------- 1 | PREFIX = ../ 2 | 3 | include $(PREFIX)make/env.mk 4 | EXCLUDE = ./19.3a.bounded-queue.c ./19.1-nester-tester.c ./19.2-RPN-calculator.c ./19.5-queue-client.c 5 | include $(PREFIX)make/generic.mk 6 | 7 | COMPILE = $(CC) -c $(CFLAGS) $< 8 | LINK = $(LD) $^ -o $@ 9 | 10 | all: $(EXECUTABLES) 19.3a.bounded-queue 19.1-nester-tester 19.2-RPN-calculator 19.5-queue-client 11 | 12 | SRC = $(PREFIX)src 13 | 14 | 19.5-queue-client: 19.5-queue-client.o $(LIBS)/queue.o $(LIBS)/error.o 15 | $(LINK) 16 | 17 | 19.5-queue-client.o: %.o : %.c $(INCS)/queue.h $(INCS)/error.h 18 | $(COMPILE) 19 | 20 | 19.1-nester-tester: 19.1-nester-tester.o stackADT3.o 21 | $(LINK) 22 | 23 | 19.2-RPN-calculator: 19.2-RPN-calculator.o stackADT3.o $(LIBS)/tokenize.o 24 | $(LINK) 25 | 26 | stackADT3.o: $(SRC)/stackADT3.c $(SRC)/stackADT.h 27 | $(COMPILE) -I$(SRC) 28 | 29 | 19.3a.bounded-queue: 19.3a.bounded-queue.o $(LIBS)/bounded-queue.o $(LIBS)/error.o 30 | $(LINK) 31 | 32 | 19.3a.bounded-queue.o: %.o : %.c $(INCS)/global-queue.h $(INCS)/error.h 33 | $(COMPILE) 34 | 35 | include $(PREFIX)make/clean.mk 36 | include $(LIBS)/makefile 37 | -------------------------------------------------------------------------------- /20/swap_bytes.c: -------------------------------------------------------------------------------- 1 | #include "test_runner.h" 2 | 3 | unsigned short int swap_bytes(unsigned short i) 4 | { 5 | return i << 8 | i >> 8; 6 | } 7 | 8 | int swap_bytes_test(void) 9 | { 10 | _assert(swap_bytes(0x1234) == 0x3412); 11 | _assert(swap_bytes(0xFF00) == 0x00FF); 12 | return 0; 13 | } 14 | int all_tests(void) 15 | { 16 | 17 | _run(swap_bytes_test); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /21/21.1-offsetof.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct s { 5 | char a; 6 | int b[2]; 7 | float c; 8 | }; 9 | 10 | int main(void) 11 | { 12 | printf(" offset size\n"); 13 | printf("struct s: %ld\t%ld\n", offsetof(struct s,a), sizeof(struct s)); 14 | /* Seems to be a 3-byte hole after the char member 'a' */ 15 | printf("s.a : %ld\t%ld\n", offsetof(struct s,a), sizeof(((struct s*)0)->a)); 16 | printf("s.b : %ld\t%ld\n", offsetof(struct s,b), sizeof(((struct s*)0)->b)); 17 | printf("s.b[1] : %ld\t%ld\n", offsetof(struct s,b[1]), sizeof(((struct s*)0)->b[1])); 18 | printf("s.c : %ld\t%ld\n", offsetof(struct s,c), sizeof(((struct s*)0)->c)); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /22/22.1-readable.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* canopen.c (Chapter 22, page 547) */ 11 | /* Checks whether a file can be opened for reading */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | static bool readable(char *file) 18 | { 19 | FILE *fp; 20 | if ((fp = fopen(file, "rb")) == NULL) 21 | return false; 22 | 23 | fclose(fp); 24 | 25 | return true; 26 | } 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | 31 | if (argc < 2) { 32 | printf("usage: %s \n", argv[0]); 33 | exit(EXIT_FAILURE); 34 | } 35 | 36 | for (int i = 1; i < argc; i++) 37 | if (readable(argv[i])) 38 | printf("Y: %s\n", argv[i]); 39 | else 40 | printf("N: %s\n", argv[i]); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /22/22.11-format-dates.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | if (argc < 2) 7 | exit(EXIT_FAILURE); 8 | int mm, dd, yyyy; 9 | char *months[13] = {"INVALID", 10 | "January", "February", "March", 11 | "April", "May", "June", 12 | "July", "August", "September", 13 | "Octobre", "November", "December"}; 14 | 15 | for (int i = 1; i < argc; i++) { 16 | sscanf(argv[i], "%2d%*[-/]%2d%*[-/]%4d", &mm, &dd, &yyyy); 17 | if (mm < 1 || mm > 12) { 18 | fprintf(stderr, "Invalid month: %d\n", mm); 19 | continue; 20 | } 21 | printf("%s %d, %4d\n", months[mm], dd, yyyy); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /22/22.14-ceasar-cipher.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define INPUT_FILENAME_SIZE FILENAME_MAX - 4 7 | #define OUTPUT_FILENAME_SIZE FILENAME_MAX 8 | 9 | int main(void) 10 | { 11 | char input[INPUT_FILENAME_SIZE + 1]; 12 | char output[OUTPUT_FILENAME_SIZE + 1]; 13 | int ch, i, shift_amount; 14 | int rc = 0; 15 | 16 | printf("Enter name of file to be encrypted: "); 17 | 18 | for (i = 0; i < INPUT_FILENAME_SIZE && (ch = getchar()) != '\n'; i++) { 19 | input[i] = output[i] = ch; 20 | } 21 | input[i] = output[i] = '\0'; 22 | strcat(output, ".enc"); 23 | 24 | printf("Enter shift amount (1-25): "); 25 | scanf("%d", &shift_amount); 26 | 27 | FILE *istream, *ostream; 28 | if ((istream = fopen(input, "r")) == NULL) { 29 | perror(input); 30 | exit(EXIT_FAILURE); 31 | } 32 | 33 | if ((ostream = fopen(output, "w")) == NULL) { 34 | perror(output); 35 | if (fclose(istream) == EOF) 36 | perror(input); 37 | exit(EXIT_FAILURE); 38 | } 39 | 40 | while ((ch = fgetc(istream)) != EOF) { 41 | if (islower(ch)) 42 | ch = (( ch - 'a') + shift_amount) % 26 + 'a'; 43 | if (isupper(ch)) 44 | ch = (( ch - 'A') + shift_amount) % 26 + 'A'; 45 | if (fputc(ch, ostream) == EOF) { 46 | perror(output); 47 | rc = -1; 48 | break; 49 | } 50 | } 51 | if (ferror(istream)) { 52 | perror(input); 53 | rc = -2; 54 | } 55 | 56 | if (fclose(istream) == EOF) { 57 | perror(input); 58 | rc = -3; 59 | } 60 | 61 | if (fclose(ostream) == EOF) { 62 | perror(output); 63 | rc = -4; 64 | } 65 | 66 | return rc; 67 | } 68 | -------------------------------------------------------------------------------- /22/22.15-justify.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* justify.c (Chapter 15, page 363) */ 11 | /* Formats a file of text */ 12 | 13 | #include 14 | #include "line.h" 15 | #include "word.h" 16 | #include "error.h" 17 | 18 | #define MAX_WORD_LEN 28 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | char word[MAX_WORD_LEN+2]; 23 | int word_len; 24 | 25 | if (argc != 3) 26 | invocation_error(argv[0], "[input file] [output file]"); 27 | 28 | if (!freopen(argv[1], "r", stdin)) 29 | exit_error(argv[0], argv[1]); 30 | 31 | if (!freopen(argv[2], "w", stdout)) { 32 | if (fclose(stdin) == EOF) 33 | perror(argv[1]); 34 | exit_error(argv[0], argv[2]); 35 | } 36 | 37 | clear_line(); 38 | for (;;) { 39 | word_len = read_word(word, MAX_WORD_LEN+1); 40 | if (word_len == 0) { 41 | flush_line(); 42 | return 0; 43 | } 44 | if (word_len + 1 > space_remaining()) { 45 | write_line(); 46 | clear_line(); 47 | } 48 | add_word(word); 49 | } 50 | if (fclose(stdin) == EOF) 51 | perror(argv[1]); 52 | if (fclose(stdout) == EOF) 53 | perror(argv[2]); 54 | } 55 | -------------------------------------------------------------------------------- /22/22.16-cp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define BLOCK_SIZE 4096 8 | 9 | static void exit_error(char *s) 10 | { 11 | perror(s); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | int main(int argc, char * argv[]) 16 | { 17 | int fd_source, fd_target, rc = 0; 18 | ssize_t n_read; 19 | unsigned char buffer[BLOCK_SIZE] = {0}; 20 | struct stat source_stat; 21 | 22 | if (argc != 3) { 23 | fprintf(stderr, "usage %s source_file target_file\n", argv[0]); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | if (stat(argv[1], &source_stat) != 0) 28 | exit_error("stat"); 29 | 30 | if ((fd_source = open(argv[1], O_RDONLY)) == -1) 31 | exit_error(argv[1]); 32 | 33 | if ((fd_target = open(argv[2], O_WRONLY|O_CREAT)) == -1) { 34 | perror(argv[2]); 35 | if (close(fd_source) == -1) 36 | perror(argv[1]); 37 | exit(EXIT_FAILURE); 38 | } 39 | 40 | if (chmod(argv[2], source_stat.st_mode) == -1) 41 | exit_error("chmod"); 42 | 43 | while ((n_read = read(fd_source, buffer, BLOCK_SIZE)) > 0) 44 | if (write(fd_target, buffer, n_read) == -1) 45 | exit_error(argv[2]); 46 | if (n_read == -1) 47 | exit_error(argv[1]); 48 | 49 | if (close(fd_source) == -1) { 50 | perror(argv[1]); 51 | rc = -1; 52 | } 53 | 54 | if (close(fd_target) == -1) { 55 | perror(argv[2]); 56 | rc = -1; 57 | } 58 | 59 | return rc; 60 | } 61 | -------------------------------------------------------------------------------- /22/22.17-format-phone.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define LINE_MAX 255 6 | int main(int argc, char *argv[]) 7 | { 8 | FILE *istream; 9 | int i; 10 | char *ch, line[LINE_MAX]; 11 | char area_code[4], exchange[4], number[5]; 12 | 13 | if (argc < 2) { 14 | fprintf(stderr, "Usage: %s [input file]\n", argv[0]); 15 | exit(EXIT_FAILURE); 16 | } 17 | 18 | if ((istream = fopen(argv[1], "r")) == NULL) { 19 | perror(argv[1]); 20 | exit(EXIT_FAILURE); 21 | } 22 | 23 | while ((fgets(line, LINE_MAX, istream))) { 24 | for (ch = line; *ch && *ch != '\n';) { 25 | for (i = 0; i < 3; ch++) 26 | if (isdigit(*ch)) 27 | area_code[i++] = *ch; 28 | area_code[i] = '\0'; 29 | 30 | for (i = 0; i < 3; ch++) 31 | if (isdigit(*ch)) 32 | exchange[i++] = *ch; 33 | exchange[i] = '\0'; 34 | 35 | for (i = 0; i < 4; ch++) 36 | if (isdigit(*ch)) 37 | number[i++] = *ch; 38 | number[i] = '\0'; 39 | } 40 | 41 | printf("(%s) %s-%s\n", area_code, exchange, number); 42 | } 43 | if (ferror(istream)) 44 | perror(argv[1]); 45 | 46 | if (fclose(istream) == EOF) { 47 | perror(argv[1]); 48 | exit(EXIT_FAILURE); 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /22/22.2-fupcase.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | int ch; 8 | FILE *fp; 9 | if (argc != 2) { 10 | fprintf(stderr, "Usage:\v %s filename\n", argv[0]); 11 | exit(EXIT_FAILURE); 12 | } 13 | 14 | if ((fp = fopen(argv[1], "r")) == NULL) { 15 | fprintf(stderr, "Error opening file %s\n", argv[1]); 16 | exit(EXIT_FAILURE); 17 | } 18 | 19 | while ((ch = fgetc(fp)) != EOF) 20 | putchar(toupper(ch)); 21 | 22 | fclose(fp); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /22/22.2.3-fopen.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char *filename = "foo.txt"; 6 | 7 | FILE *fp; 8 | 9 | if ((fp = fopen(filename, "r"))) { 10 | printf("%s can be read.\n", filename); 11 | fclose(fp); /* close was outside of the block, would have been called after failure on open */ 12 | } else { 13 | printf("can't read jack shit.\n"); 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /22/22.3-formatted-io.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void ex_4(void) 4 | { 5 | char *format = "%#012.5g\n"; 6 | puts("00000083.736"); 7 | printf(format, 83.7361); 8 | puts("000000029748"); 9 | printf(format, 29748.6607); 10 | puts("000000029748"); 11 | printf(format, 105493234.0); 12 | } 13 | void ex_5(void) 14 | { 15 | printf("%.4d\n", 12); 16 | printf("%04d\n", 12); 17 | printf("%.4d\n", 12345); 18 | printf("%04d\n", 12345); 19 | } 20 | 21 | void wp(int i) 22 | { 23 | printf((i == 1) ? "%d widget\n" : "%d widgets\n", i); 24 | } 25 | 26 | void ex_6(void) 27 | { 28 | wp(1); 29 | wp(2); 30 | wp(0); 31 | } 32 | 33 | void ex_7(void) 34 | { 35 | char *a = "10 20 30\n"; 36 | char *b = "1.0 2.0 3.0\n"; 37 | char *c = "0.1 0.2 0.3\n"; 38 | char *d = ".1 .2 .3\n"; 39 | char *fmt = "%d%f%d"; 40 | char *out = "i: %d, f: %f, j: %d, n: %d\n"; 41 | int i = 0, j = 0, n = 0; 42 | float f = 0.0; 43 | 44 | n = sscanf(a, fmt, &i, &f, &j); 45 | printf(out, i, f, j, n); 46 | 47 | n = sscanf(b, fmt, &i, &f, &j); 48 | printf(out, i, f, j, n); 49 | 50 | n = sscanf(c, fmt, &i, &f, &j); 51 | printf(out, i, f, j, n); 52 | 53 | n = sscanf(d, fmt, &i, &f, &j); 54 | printf(out, i, f, j, n); 55 | 56 | } 57 | int main(void) 58 | { 59 | ex_4(); 60 | ex_5(); 61 | ex_6(); 62 | ex_7(); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /22/22.3.7-file-position.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define RECORD_SIZE 64 4 | 5 | int fseek_calls(void) 6 | { 7 | FILE *fp = fopen("dummy", "rb"); 8 | if (!fp) 9 | return -1; 10 | int n = 52; 11 | /* a) move to the beginning of record n */ 12 | fseek(fp, RECORD_SIZE * n, SEEK_SET); 13 | 14 | /* b) move to the beginning of the last record in the file */ 15 | fseek(fp, -RECORD_SIZE, SEEK_END); 16 | 17 | /* c) move forward one record */ 18 | fseek(fp, RECORD_SIZE, SEEK_CUR); 19 | 20 | /* d) move backward 2 records */ 21 | fseek(fp, -(2 * RECORD_SIZE), SEEK_CUR); 22 | 23 | return 0; 24 | } 25 | 26 | int main(void) 27 | { 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /22/22.3.8-parser.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | char *pattern = " #%[0123456789,]"; 8 | char sales_rank[255]; 9 | 10 | sscanf(" #123", pattern, &sales_rank); 11 | assert(strcmp(sales_rank, "123") == 0); 12 | 13 | sscanf(" #999,999,901 ", pattern, &sales_rank); 14 | assert(strcmp(sales_rank, "999,999,901") == 0); 15 | 16 | sscanf(" #24,675", pattern, &sales_rank); 17 | assert(strcmp(sales_rank, "24,675") == 0); 18 | 19 | sscanf("#1", pattern, &sales_rank); 20 | assert(strcmp(sales_rank, "1") == 0); 21 | 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /22/22.4-character-io.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int count_periods(const char *filename) 5 | { 6 | FILE *fp; 7 | int ch, n = 0; 8 | if ((fp = fopen(filename, "r"))){ 9 | while ((ch = fgetc(fp)) != EOF) 10 | if (ch == '.') 11 | n++; 12 | fclose(fp); 13 | } 14 | return n; 15 | } 16 | 17 | int line_length(const char *filename, int n) 18 | { 19 | FILE *fp; 20 | int line = 1, ch, len = 0; 21 | 22 | if ((fp = fopen(filename, "r"))) { 23 | while ((ch = fgetc(fp)) != EOF) { 24 | if (ch == '\n') { 25 | if (line == n) { 26 | fclose(fp); 27 | return len; 28 | } 29 | len = 0; 30 | line++; 31 | } else 32 | len++; 33 | } 34 | fclose(fp); 35 | } 36 | return 0; 37 | } 38 | int main(void) 39 | { 40 | assert(count_periods(__FILE__) == 3); 41 | assert(line_length(__FILE__, 1) == 18); 42 | assert(line_length(__FILE__, 5) == 1); 43 | assert(line_length(__FILE__, 17) == 44); 44 | assert(line_length(__FILE__, 60) == 0); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /22/22.5-xor.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* xor.c (Chapter 20, page 515) */ 11 | /* Performs XOR encryption */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #define KEY '&' 20 | 21 | static void exit_error(char *program, char *file) 22 | { 23 | fprintf(stderr, "%s: %s: %s\n", program, file, strerror(errno)); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | int main(int argc, char *argv[]) 28 | { 29 | int ch; 30 | 31 | if (argc != 3) { 32 | fprintf(stderr, "Usage: %s \n", argv[0]); 33 | exit(EXIT_FAILURE); 34 | } 35 | 36 | FILE *in, *out; 37 | 38 | if ((in = fopen(argv[1], "rb")) == NULL) 39 | exit_error(argv[0], argv[1]); 40 | 41 | if ((out = fopen(argv[2], "wb")) == NULL) 42 | exit_error(argv[0], argv[2]); 43 | 44 | while ((ch = fgetc(in)) != EOF) { 45 | if (fputc(ch ^ KEY, out) == EOF) 46 | exit_error(argv[0], argv[2]); 47 | } 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /22/22.7-rle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "run-length-encoding.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | char *program = argv[0]; 8 | if (argc != 2) 9 | invocation_error(program, "[file]"); 10 | 11 | char *iname = argv[1]; 12 | FILE *istream; 13 | if ((istream = fopen(iname, "rb")) == NULL) 14 | exit_error(program, iname); 15 | 16 | char *oname = build_output_file_name(iname); 17 | FILE *ostream; 18 | if ((ostream = fopen(oname, "wb")) == NULL) { 19 | print_error(program, oname); 20 | free(oname); 21 | if (fclose(istream) == EOF) 22 | exit_error(program, iname); 23 | exit(EXIT_FAILURE); 24 | } 25 | 26 | /* 27 | * Process 28 | */ 29 | if (is_rle_file(oname)) 30 | encode_rle(istream, ostream); 31 | else 32 | decode_rle(istream, ostream); 33 | 34 | /* 35 | * Clean up 36 | */ 37 | free(oname); 38 | 39 | if (fclose(istream) == EOF) 40 | print_error(program, iname); 41 | 42 | if (fclose(ostream) == EOF) 43 | exit_error(program, oname); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /22/parts-io-profiler.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "parts.h" 4 | 5 | /* 6 | OSX (Mach) limits (Snow Leopard) 7 | 2147483584 = (2147483648 - 64) = 33554431* 64 bytes 8 | max that memory will hold before corruption 9 | 1 more record is INT_MAX 10 | 11 | Linux -- No limit found, but only tested up to 4GB ((67108864 + 1) * 64) 12 | */ 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | if (argc != 3) 17 | invocation_error(argv[0], "[input file] [output file]"); 18 | puts(argv[0]); 19 | 20 | Parts db; 21 | time_t start_time = time(NULL); 22 | clock_t start_clock = clock(); 23 | if ((db = load_parts(argv[1])) == NULL) 24 | print_error( __FILE__, argv[1]); 25 | time_t end_time = time(NULL); 26 | clock_t end_clock = clock() - start_clock; 27 | 28 | printf("p %g:\tr %g:\tReading %ld from %s\n", end_clock / (double) CLOCKS_PER_SEC, difftime(end_time, start_time), size(db), argv[1]); 29 | 30 | start_time = time(NULL); 31 | start_clock = clock(); 32 | if (dump(argv[2], db) != 0) 33 | print_error( __FILE__, argv[2]); 34 | end_time = time(NULL); 35 | end_clock = clock() - start_clock; 36 | 37 | printf("p %g:\tr %g:\tWriting %s\n", end_clock / (double) CLOCKS_PER_SEC, difftime(end_time, start_time), argv[2]); 38 | puts(""); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /23/23.8-numchar.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "test_runner.h" 3 | 4 | int numchar(const char *s, char ch) 5 | { 6 | int count = 0; 7 | const char *p = s; 8 | while ((p = strchr(p, ch))) { 9 | count++; 10 | p++; 11 | } 12 | 13 | return count; 14 | } 15 | int numchar_test(void) 16 | { 17 | _assert(numchar("aardvark", 'a') == 3); 18 | _assert(numchar("aardvark", 'q') == 0); 19 | _assert(numchar("aardvark", 'k') == 1); 20 | 21 | return 0; 22 | } 23 | int all_tests(void) 24 | { 25 | _run(numchar_test); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /25/25.2-print-lconv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define CURRENCY_MAX 16 8 | int main(int argc, char *argv[]) 9 | { 10 | if (argc < 2) { 11 | fprintf(stderr, "%s locale\n", argv[0]); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | char *l = setlocale(LC_ALL, argv[1]); 16 | if (!l) { 17 | fprintf(stderr, "setlocale() failed for %s\n", argv[1]); 18 | exit(EXIT_FAILURE); 19 | } 20 | puts(l); 21 | 22 | struct lconv *locale = localeconv(); 23 | printf("decimal_point = \"%s\"\n", locale->decimal_point); 24 | printf("thousands_sep = \"%s\"\n", locale->thousands_sep); 25 | printf("grouping = \"%s\" : %d\n", locale->grouping, atoi(locale->grouping)); 26 | printf("mon_decimal_point = \"%s\"\n", locale->mon_decimal_point); 27 | printf("mon_thousands_sep = \"%s\"\n", locale->mon_thousands_sep); 28 | printf("mon_grouping = \"%s\" : %d\n", locale->mon_grouping, atoi(locale->mon_grouping)); 29 | printf("positive_sign = \"%s\"\n", locale->positive_sign); 30 | printf("negative_sign = \"%s\"\n", locale->negative_sign); 31 | printf("currency_symbol = \"%s\"\n", locale->currency_symbol); 32 | printf("frac_digits = %d\n", locale->frac_digits); 33 | puts("etc."); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # tested with GNU make 3.81 2 | PREFIX = ./ 3 | include make/env.mk 4 | #### Don't build source in directories with their own makefiles ### 5 | #### or the example programs from the textbook ### 6 | MF_DIRS = $(dir $(shell find . -type f -name 'makefile')) 7 | SELF_MAKERS = $(foreach mf_dir, $(MF_DIRS), $(wildcard $(mf_dir)*.c)) 8 | EXCLUDE = $(shell find ./src -name '*.c') $(SELF_MAKERS) 9 | 10 | include make/generic.mk 11 | all: $(EXECUTABLES) 12 | 13 | include make/clean.mk 14 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # c-programming 2 | 3 | This is my working repo of problem solutions for Dr. K.N. King's text [C Programming: A Modern Appraoch, 2nd Ed.](http://knking.com/books/c2). 4 | -------------------------------------------------------------------------------- /data/100k-parts.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twcamper/c-programming/f0cb17b8cae27da35dd8cf2528dcb39bfe017698/data/100k-parts.dat -------------------------------------------------------------------------------- /data/21-parts.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twcamper/c-programming/f0cb17b8cae27da35dd8cf2528dcb39bfe017698/data/21-parts.dat -------------------------------------------------------------------------------- /data/consecutive-newlines.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 3 5 | 6 | 7 | 8 | 4 9 | 10 | 2 11 | 1 12 | 13 | 14 | 15 | 16 | 5 17 | 18 | 19 | 20 | 21 | 22 | 6 23 | 24 | 25 | 3 26 | 27 | -------------------------------------------------------------------------------- /data/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twcamper/c-programming/f0cb17b8cae27da35dd8cf2528dcb39bfe017698/data/empty.txt -------------------------------------------------------------------------------- /data/flights.txt: -------------------------------------------------------------------------------- 1 | 0:20 2:30 2 | 4:35 6:15 3 | 8:00 10:16 4 | 9:43 11:52 5 | 11:19 13:31 6 | 12:47 15:00 7 | 13:15 15:30 8 | 14:00 16:08 9 | 14:20 16:28 10 | 15:45 17:55 11 | 16:00 18:10 12 | 16:40 18:55 13 | 17:10 19:15 14 | 18:23 20:16 15 | 19:00 21:20 16 | 19:40 22:00 17 | 20:15 22:20 18 | 21:00 23:10 19 | 21:45 23:58 20 | 22:10 0:15 21 | 23:20 1:20 22 | -------------------------------------------------------------------------------- /data/has-blanks.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file has 54 cases of white lightnin' and moonshine. 4 | 5 | 6 | 7 | Oh my golly, we're on the road again. 8 | 9 | That one, above, had tabs. 10 | . 11 | 12 | -------------------------------------------------------------------------------- /data/no-newline.txt: -------------------------------------------------------------------------------- 1 | no way -------------------------------------------------------------------------------- /data/one-liner.txt: -------------------------------------------------------------------------------- 1 | one 2 | -------------------------------------------------------------------------------- /data/one-part.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twcamper/c-programming/f0cb17b8cae27da35dd8cf2528dcb39bfe017698/data/one-part.dat -------------------------------------------------------------------------------- /data/runs.txt: -------------------------------------------------------------------------------- 1 | 1223334444555556666667777777888888889999999990 2 | -------------------------------------------------------------------------------- /data/two-parts.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twcamper/c-programming/f0cb17b8cae27da35dd8cf2528dcb39bfe017698/data/two-parts.dat -------------------------------------------------------------------------------- /data/us-phone-numbers.txt: -------------------------------------------------------------------------------- 1 | 404.817.6900 2 | (215) 686-1776 3 | 312-746-6000 4 | 612 945 -1522 5 | 877 275 5273 6 | 6173434200 7 | -------------------------------------------------------------------------------- /data/windows.txt: -------------------------------------------------------------------------------- 1 | PIXIES 2 | Doolittle 3 | {MFSL SACD HYRBID} 4 | ------------------ 5 | 01 Debaser 6 | 02 Tame 7 | 03 Wave Of Mutilation 8 | 04 I Bleed 9 | 05 Here Comes Your Man 10 | 06 Dead 11 | 07 Monkey Gone To Heaven 12 | 08 Mr. Grieves 13 | 09 Crackity Jones 14 | 10 La La Love You 15 | 11 No. 13 Baby 16 | 12 There Goes My Gun 17 | 13 Hey 18 | 14 Silver 19 | 15 Gouge Away 20 | 21 | Label: Mobile Fidelity Sound Labs 22 | Catalog Number: UDSACD 2033 23 | Format: Stereo SACD Hybrid 24 | Country Of Origin: US 25 | Date Of Release: March 2008 26 | -------------------------------------------------------------------------------- /include/bounded-queue.h: -------------------------------------------------------------------------------- 1 | #ifndef BOUNDED_QUEUE_H 2 | #define BOUNDED_QUEUE_H 3 | 4 | #include 5 | 6 | /* A Queue is a pointer to queue_type struct */ 7 | typedef struct queue_type *Queue; 8 | typedef int Item; 9 | 10 | Queue create_queue(int); 11 | void destroy(Queue); 12 | void insert_item(Queue, Item); 13 | Item remove_item(Queue); 14 | Item front(Queue); 15 | Item rear(Queue); 16 | bool is_empty(Queue); 17 | int depth(Queue); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/chess.h: -------------------------------------------------------------------------------- 1 | #ifndef CHESS_H 2 | #define CHESS_H 3 | 4 | typedef enum {BLACK = 0, WHITE = 255} Color; 5 | typedef enum {EMPTY, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING} Piece; 6 | 7 | 8 | typedef struct { Color color; Piece piece; } Square; 9 | 10 | extern Square board[8][8]; 11 | 12 | void new_board(Square board[][8]); 13 | int piece_value(Piece); 14 | #endif 15 | -------------------------------------------------------------------------------- /include/error.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void invocation_error(char *program, char *usage); 7 | void memory_error(char *file, unsigned int line, const char *func); 8 | void print_error(char *, char *); 9 | void exit_error(char *, char *); 10 | int is_file_name_error(int); 11 | -------------------------------------------------------------------------------- /include/find-departure.h: -------------------------------------------------------------------------------- 1 | #ifndef FIND_DEPARTURE_H 2 | #define FIND_DEPARTURE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define DATA_ERROR(f, l, s) \ 13 | do { \ 14 | fprintf(stderr, "Invalid data %s:%ld '%s'\n", (f), (l), (s)); \ 15 | data_error = true; \ 16 | } while (0) 17 | 18 | #define TIME_STR_SIZE 6 19 | #define FILE_PATH "data/flights.txt" 20 | 21 | void find_closest_flight(int, int *, int *); 22 | void print_am_pm(int); 23 | int get_valid_input(void); 24 | int to_minutes(char *); 25 | bool is_format_valid(char *); 26 | void convert(char *, int *, int *); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/global-queue.h: -------------------------------------------------------------------------------- 1 | #ifndef GLOBAL_QUEUE_H 2 | #define GLOBAL_QUEUE_H 3 | 4 | #include 5 | 6 | typedef int Item; 7 | 8 | void insert_item(Item i); 9 | Item remove_item(void); 10 | Item front(void); 11 | Item rear(void); 12 | bool is_empty(void); 13 | void clear_queue(void); 14 | int queue_size(void); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/inventory-view.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_VIEW_H 2 | #define INVENTORY_VIEW_H 3 | 4 | #include 5 | #include "readline.h" 6 | #include "parts.h" 7 | 8 | void insert(Parts); 9 | void erase(Parts); 10 | void search(Parts); 11 | void update(Parts); 12 | void print(Parts); 13 | Parts load_db(Parts); 14 | void save_db(Parts); 15 | Parts init_db(char *); 16 | #endif 17 | -------------------------------------------------------------------------------- /include/part-type.h: -------------------------------------------------------------------------------- 1 | #ifndef PART_TYPE_H 2 | #define PART_TYPE_H 3 | #include "part.h" 4 | struct part_type 5 | { 6 | PartNumber number; 7 | char name[NAME_LEN+1]; 8 | PartQuantity on_hand; 9 | PartPrice price; 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /include/part.h: -------------------------------------------------------------------------------- 1 | #ifndef PART_H 2 | #define PART_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #define NAME_LEN 51 /* size adjusted to prevent holes/padding in the struct. 10 | * This ensures consistency in the test checksums 11 | */ 12 | 13 | typedef struct part_type *Part; 14 | typedef int PartNumber; 15 | typedef int PartQuantity; 16 | typedef int PartPrice; 17 | 18 | Part new_part(void); 19 | Part set_part(PartNumber, char *, PartQuantity, PartPrice); 20 | bool set_part_number(Part, PartNumber); 21 | void set_part_name(Part, char *); 22 | bool set_part_on_hand(Part, PartQuantity); 23 | bool change_part_on_hand(Part, PartQuantity); 24 | bool set_part_price(Part, PartPrice); 25 | size_t get_part_record_size(void); 26 | PartNumber get_part_number(Part); 27 | char * get_part_name(Part); 28 | PartQuantity get_part_on_hand(Part); 29 | PartPrice get_part_price(Part); 30 | void destroy_part(Part); 31 | void init_locale(void); 32 | char * dollars(Part); 33 | void print_part(Part); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/parts.h: -------------------------------------------------------------------------------- 1 | #ifndef PARTS_H 2 | #define PARTS_H 3 | #if defined(__linux__) || defined(__linux) || defined(__gnu_linux__) 4 | /* for off_t. 5 | * including sys/types.h is a frowned upon hack, 6 | * but I can't figure out the feature macro combination 7 | * to make it work. 8 | */ 9 | #include 10 | #endif 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "part.h" 17 | #include "error.h" 18 | 19 | typedef struct parts_type *Parts; 20 | 21 | Parts new_db(size_t); 22 | void destroy_db(Parts); 23 | int insert_part(Parts, Part); 24 | int delete_part(Parts, PartNumber); 25 | Part find_part(Parts, PartNumber); 26 | Part approximate_part(Parts, PartNumber); 27 | void load(Parts); 28 | int dump(char *, Parts); 29 | int flush_to_disk(char *, Parts); 30 | Parts read_parts_file(char *infile, int(*process_records)(Parts, FILE *, off_t)); 31 | Parts load_parts(char *); 32 | void iterate(Parts, void (*)(Part)); 33 | void iterate_by_page(Parts, size_t, void (*)(Part), int (*)(void)); 34 | size_t size(Parts); 35 | Part last_part(Parts); 36 | #endif 37 | -------------------------------------------------------------------------------- /include/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | 6 | /* A Queue is a pointer to queue_type struct */ 7 | typedef struct queue_type *Queue; 8 | typedef int Item; 9 | 10 | Queue create_queue(void); 11 | void destroy(Queue); 12 | void insert_item(Queue, Item); 13 | Item remove_item(Queue); 14 | Item front(Queue); 15 | Item rear(Queue); 16 | void clear(Queue); 17 | bool is_empty(Queue); 18 | int depth(Queue); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/rectangle.h: -------------------------------------------------------------------------------- 1 | #ifndef RECTANGLE_H 2 | #define RECTANGLE_H 3 | 4 | #include 5 | 6 | typedef struct {int x, y;} point; 7 | typedef struct {point upper_left, lower_right; } rectangle; 8 | 9 | int area(rectangle r); 10 | point center(rectangle r); 11 | rectangle move(rectangle r, int x, int y); 12 | bool is_inside(rectangle r, point p); 13 | int height(rectangle r); 14 | int width(rectangle r); 15 | #endif 16 | -------------------------------------------------------------------------------- /include/run-length-encoding.h: -------------------------------------------------------------------------------- 1 | #ifndef RUN_LENGTH_ENCODING_H 2 | #define RUN_LENGTH_ENCODING_H 3 | #include 4 | #include 5 | #include 6 | #include "error.h" 7 | 8 | void encode_rle(FILE *, FILE *); 9 | void decode_rle(FILE *, FILE *); 10 | bool is_rle_file(char *); 11 | char *build_output_file_name(char *); 12 | #endif 13 | -------------------------------------------------------------------------------- /include/test_runner.h: -------------------------------------------------------------------------------- 1 | /* Thanks to Eric Radman, bitbucket.org/eradman/tdd-in-c */ 2 | #include 3 | 4 | #define RED "\033[0;36m" 5 | #define GREEN "\033[0;32m" 6 | #define END_COLOR "\033[0m" 7 | int tests_run = 0; 8 | int assertions = 0; 9 | 10 | #define _assert(e) \ 11 | do { \ 12 | if (!(e)) { \ 13 | printf("%s%s:%u (%s) failed assertion:\v(%s)\n", RED, __FILE__, __LINE__, __func__, #e); \ 14 | return 1; \ 15 | } else { \ 16 | assertions++; \ 17 | } \ 18 | } while (0) 19 | 20 | #ifdef TEST_VERBOSE 21 | #define _run(test) do { printf("\t%s\n", #test); int r=test(); tests_run++; if(r) return r; } while(0) 22 | #else 23 | #define _run(test) do { int r=test(); tests_run++; if(r) return r; } while(0) 24 | #endif 25 | 26 | static int all_tests(void); 27 | 28 | int main(int argc, char *argv[]) { 29 | if (argc < 0) 30 | puts("Would the compiler please shut up about unused argc?"); 31 | 32 | int result = all_tests(); 33 | if (result == 0) 34 | printf("%sPASS\t", GREEN); 35 | else 36 | printf("%sFAIL\t", RED); 37 | printf("Tests: %d\tAssertions: %d\t%s\n%s", tests_run, assertions, argv[0], END_COLOR); 38 | 39 | return result != 0; 40 | } 41 | -------------------------------------------------------------------------------- /include/time_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef TIME_HELPER_H 2 | #define TIME_HELPER_H 3 | 4 | #include 5 | #include 6 | 7 | time_t random_time(void); 8 | struct tm *random_tm(void); 9 | #endif 10 | -------------------------------------------------------------------------------- /include/tokenize.h: -------------------------------------------------------------------------------- 1 | #ifndef TOKENIZE_H 2 | #define TOKENIZE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | size_t tokenize(char *string, char **tokens); 9 | #endif 10 | -------------------------------------------------------------------------------- /include/word.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* word.h (Chapter 15, page 361) */ 11 | 12 | #ifndef WORD_H 13 | #define WORD_H 14 | 15 | /********************************************************** 16 | * read_word: Reads the next word from the input and * 17 | * stores it in word. Makes word empty if no * 18 | * word could be read because of end-of-file. * 19 | * Truncates the word if its length exceeds * 20 | * len. * 21 | **********************************************************/ 22 | int read_word(char *word, int len); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /lib/chess.c: -------------------------------------------------------------------------------- 1 | #include "chess.h" 2 | 3 | void new_board(Square board[][8]) 4 | { 5 | int rank, file; 6 | 7 | board[0][0] = (Square) {BLACK, ROOK}; 8 | board[0][1] = (Square) {BLACK, KNIGHT}; 9 | board[0][2] = (Square) {BLACK, BISHOP}; 10 | board[0][3] = (Square) {BLACK, QUEEN}; 11 | board[0][4] = (Square) {BLACK, KING}; 12 | board[0][5] = (Square) {BLACK, BISHOP}; 13 | board[0][6] = (Square) {BLACK, KNIGHT}; 14 | board[0][7] = (Square) {BLACK, ROOK}; 15 | 16 | for (file = 0; file < 8; file++) 17 | board[1][file] = (Square) {BLACK, PAWN}; 18 | 19 | for (rank = 2; rank < 6; rank++) 20 | for (file = 0; file < 8; file++) 21 | board[rank][file] = (Square) {BLACK, EMPTY}; 22 | 23 | for (file = 0; file < 8; file++) 24 | board[6][file] = (Square) {WHITE, PAWN}; 25 | 26 | board[7][0] = (Square) {WHITE, ROOK}; 27 | board[7][1] = (Square) {WHITE, KNIGHT}; 28 | board[7][2] = (Square) {WHITE, BISHOP}; 29 | board[7][3] = (Square) {WHITE, QUEEN}; 30 | board[7][4] = (Square) {WHITE, KING}; 31 | board[7][5] = (Square) {WHITE, BISHOP}; 32 | board[7][6] = (Square) {WHITE, KNIGHT}; 33 | board[7][7] = (Square) {WHITE, ROOK}; 34 | } 35 | int piece_value(Piece p) 36 | { 37 | static const int values[] = {0, 1, 3, 3, 5, 9, 200}; 38 | return values[p]; 39 | } 40 | -------------------------------------------------------------------------------- /lib/error.c: -------------------------------------------------------------------------------- 1 | #include "error.h" 2 | 3 | void invocation_error(char *program, char *usage) 4 | { 5 | fprintf(stderr, "Usage: %s %s\n", program, usage); 6 | exit(1); 7 | } 8 | 9 | void memory_error(char *file, unsigned int line, const char *func) 10 | { 11 | fprintf(stderr, "Memory Allocation Failure: %s:%d in function %s()\n", file, line, func); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | void print_error(char *program, char *s2) 16 | { 17 | fprintf(stderr, "%s: %s: %s\n", program, s2, strerror(errno)); 18 | } 19 | void exit_error(char *program, char *s2) 20 | { 21 | print_error(program, s2); 22 | exit(EXIT_FAILURE); 23 | } 24 | int is_file_name_error(int e) 25 | { 26 | if ((strcmp(strerror(e), "No such file or directory") == 0) || 27 | (strcmp(strerror(e), "Is a directory") == 0) || 28 | (strcmp(strerror(e), "File name too long") == 0)) 29 | return 1; 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /lib/find-departure-unbuffered.c: -------------------------------------------------------------------------------- 1 | #include "find-departure.h" 2 | 3 | void find_closest_flight(int requested_departure, int *departure_time, int *arrival_time) 4 | { 5 | int diff, m; 6 | FILE *fp; 7 | char line[TIME_STR_SIZE * 2 + 1]; 8 | char d[TIME_STR_SIZE], a[TIME_STR_SIZE]; 9 | bool read_error = false, data_error = false; 10 | size_t l; 11 | 12 | if ((fp = fopen(FILE_PATH, "r")) == NULL) { 13 | perror(FILE_PATH); 14 | exit(EXIT_FAILURE); 15 | } 16 | int minimum_difference = 23*60+59; 17 | for (l = 0;fgets(line, sizeof(line), fp) != NULL; l++) { 18 | sscanf(line, "%s %s", d, a); 19 | if ((m = to_minutes(d)) == -1) { 20 | DATA_ERROR(FILE_PATH, l + 1, d); 21 | break; 22 | } 23 | diff = abs(requested_departure - m); 24 | if (diff < minimum_difference) { 25 | minimum_difference = diff; 26 | *departure_time = m; 27 | if ((m = to_minutes(a)) == -1) { 28 | DATA_ERROR(FILE_PATH, l + 1, a); 29 | break; 30 | } 31 | *arrival_time = m; 32 | } 33 | } 34 | if (!feof(fp) || ferror(fp)) { 35 | if (!data_error) { 36 | perror(FILE_PATH); 37 | read_error = true; 38 | errno = 0; 39 | } 40 | } 41 | if (feof(fp) && l == 0) { 42 | fprintf(stderr, "Empty data file: %s\n", FILE_PATH); 43 | data_error = true; 44 | } 45 | 46 | if (fclose(fp) == EOF || read_error || data_error) { 47 | if (!data_error && !read_error) 48 | perror(FILE_PATH); 49 | exit(EXIT_FAILURE); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/global-queue.c: -------------------------------------------------------------------------------- 1 | #include "global-queue.h" 2 | #include "error.h" 3 | #include 4 | 5 | typedef struct node 6 | { 7 | Item item; 8 | struct node *next; 9 | } Node; 10 | 11 | struct Queue 12 | { 13 | Node *front; 14 | Node *rear; 15 | int depth; 16 | }; 17 | 18 | static struct Queue _queue = {.front = NULL, .rear = NULL, .depth = 0 }; 19 | 20 | static Node * create_node(Item value) 21 | { 22 | Node *n = malloc(sizeof(Node)); 23 | if (!n) 24 | memory_error(__FILE__, __LINE__, __func__); 25 | 26 | n->item = value; 27 | n->next = NULL; 28 | return n; 29 | } 30 | 31 | void insert_item(Item i) 32 | { 33 | if (_queue.depth == 0) { 34 | _queue.front = create_node(i); 35 | _queue.rear = _queue.front; 36 | } else { 37 | _queue.rear->next = create_node(i); 38 | _queue.rear = _queue.rear->next; 39 | } 40 | 41 | _queue.depth++; 42 | } 43 | Item remove_item(void) 44 | { 45 | Node *old_front = _queue.front; 46 | Item value = old_front->item; 47 | _queue.front = _queue.front->next; 48 | free(old_front); 49 | _queue.depth--; 50 | return value; 51 | } 52 | Item front(void) 53 | { 54 | return _queue.front->item; 55 | } 56 | Item rear(void) 57 | { 58 | return _queue.rear->item; 59 | } 60 | bool is_empty(void) 61 | { 62 | return _queue.depth == 0; 63 | } 64 | void clear_queue(void) 65 | { 66 | Node *next = NULL; 67 | for (Node *n = _queue.front; n; n = next) { 68 | next = n->next; 69 | free(n); 70 | } 71 | _queue.front = NULL; 72 | _queue.depth = 0; 73 | _queue.rear = NULL; 74 | } 75 | int queue_size(void) 76 | { 77 | return _queue.depth; 78 | } 79 | -------------------------------------------------------------------------------- /lib/makefile: -------------------------------------------------------------------------------- 1 | %.o : %.c $(INCS)/%.h 2 | $(CC) -c $(CFLAGS) $< -o $@ 3 | -------------------------------------------------------------------------------- /lib/rectangle.c: -------------------------------------------------------------------------------- 1 | #include "rectangle.h" 2 | 3 | int area(rectangle r) 4 | { 5 | return height(r) * width(r); 6 | } 7 | point center(rectangle r) 8 | { 9 | return (point) {width(r) / 2, height(r) / 2}; 10 | } 11 | rectangle move(rectangle r, int x, int y) 12 | { 13 | r.upper_left.x += x; 14 | r.lower_right.x += x; 15 | r.upper_left.y += y; 16 | r.lower_right.y += y; 17 | 18 | return r; 19 | } 20 | bool is_inside(rectangle r, point p) 21 | { 22 | if (p.x >= r.upper_left.x && 23 | p.x <= r.lower_right.x && 24 | p.y >= r.upper_left.y && 25 | p.y <= r.lower_right.y) { 26 | return true; 27 | } 28 | 29 | return false; 30 | } 31 | int height(rectangle r) 32 | { 33 | return r.lower_right.y - r.upper_left.y; 34 | } 35 | int width(rectangle r) 36 | { 37 | return r.lower_right.x - r.upper_left.x; 38 | } 39 | -------------------------------------------------------------------------------- /lib/time_helper.c: -------------------------------------------------------------------------------- 1 | #include "time_helper.h" 2 | 3 | time_t random_time(void) 4 | { 5 | return (time_t) rand() % (int) time(NULL); 6 | } 7 | 8 | struct tm *random_tm(void) 9 | { 10 | time_t t = random_time(); 11 | 12 | return localtime(&t); 13 | } 14 | -------------------------------------------------------------------------------- /lib/tokenize.c: -------------------------------------------------------------------------------- 1 | #include "tokenize.h" 2 | 3 | size_t tokenize(char *string, char **tokens) 4 | { 5 | register bool in_token = false; 6 | size_t t; 7 | char *ch_ptr; 8 | for (t = 0, ch_ptr = string; *ch_ptr; ch_ptr++) { 9 | if (isspace(*ch_ptr)) { 10 | if (in_token) 11 | /* this is the first char after a token, 12 | * and this is how we tokenize our string */ 13 | *ch_ptr = '\0'; 14 | in_token = false; 15 | } else /* NOT A SPACE */ 16 | if (!in_token) { 17 | /* this is the frist char of our token, */ 18 | /* so we put a pointer to it in our list */ 19 | tokens[t++] = ch_ptr; 20 | in_token = true; 21 | } 22 | } 23 | return t; 24 | } 25 | -------------------------------------------------------------------------------- /lib/word.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* word.c (Chapter 15, page 363) */ 11 | 12 | #include 13 | #include "word.h" 14 | 15 | int read_char(void) 16 | { 17 | int ch = getchar(); 18 | if (ch == '\r' || ch == '\n' || ch == '\t') 19 | return ' '; 20 | return ch; 21 | } 22 | 23 | int read_word(char *word, int len) 24 | { 25 | int ch, pos = 0; 26 | 27 | while ((ch = read_char()) == ' ') 28 | ; 29 | while (ch != ' ' && ch != EOF) { 30 | if (pos < len) 31 | word[pos++] = ch; 32 | ch = read_char(); 33 | } 34 | if (pos == len) 35 | word[pos - 1] = '*'; 36 | 37 | word[pos] = '\0'; 38 | return pos; 39 | } 40 | -------------------------------------------------------------------------------- /make/clean.mk: -------------------------------------------------------------------------------- 1 | .PHONY : clean clean-obj clean-bin 2 | 3 | clean: clean-obj clean-archives clean-bin 4 | 5 | XARGS_RM = xargs rm -fv 6 | CLEAN_PATH = ./$(CLEAN) 7 | 8 | clean-obj: 9 | @find $(CLEAN_PATH) -name '*.o' | $(XARGS_RM) 10 | @find $(CLEAN_PATH) -name '*.gch' | $(XARGS_RM) 11 | 12 | clean-archives: 13 | @find $(CLEAN_PATH) -name '*.a' | $(XARGS_RM) 14 | @find $(CLEAN_PATH) -name '*.so' | $(XARGS_RM) 15 | 16 | clean-bin: 17 | @find $(CLEAN_PATH) -perm +111 -type f | grep -vE '\.git' | $(XARGS_RM) 18 | 19 | -------------------------------------------------------------------------------- /make/env.mk: -------------------------------------------------------------------------------- 1 | SHELL = /usr/bin/env sh 2 | DBGFLAGS = -g3 -gdwarf-2 3 | # 4 | # Use flag -O (optimize) to make clang inline functions that 5 | # are also extern (e.g., sqrt() in math.h). GCC does that by default. 6 | # We get linker 'undefined reference' errors if such functions aren't inlined 7 | OFLAGS = 8 | CC = clang 9 | LD = clang 10 | LIBS = $(PREFIX)lib 11 | INCS = $(PREFIX)include 12 | 13 | # Flag -Wextra replaces -W in newer gcc's. Use -W if you have an old version of gcc and get an arg error. 14 | # 15 | # 'override' alows us to prepend from the command line (GNU make manual, 6.7) 16 | override CFLAGS += $(OFLAGS) -I$(INCS) $(DBGFLAGS) -Wall -Wextra -pedantic -std=c99 17 | -------------------------------------------------------------------------------- /make/generic.mk: -------------------------------------------------------------------------------- 1 | ALL_SRC = $(shell find . -name '*.c' | tr '\n' ' ') 2 | 3 | # includer must set EXCLUDE list before the include line 4 | SRCS = $(filter-out $(EXCLUDE), $(ALL_SRC)) 5 | OBJECTS = $(SRCS:.c=.o) 6 | EXECUTABLES = $(SRCS:.c=) 7 | H_SRCS = $(shell find . -name '*.h' | tr '\n' ' ') 8 | HEADERS = $(H_SRCS:.h=.gch) 9 | 10 | warn: 11 | @echo You probably mean "'all'" 12 | 13 | #### Build all executable targets, using a 'Static Pattern Rule' (GNU make manual, 4.11) #### 14 | $(EXECUTABLES) : % : %.o 15 | $(LD) $< -o $@ 16 | 17 | #### compiled object files #### 18 | $(OBJECTS) : %.o : %.c 19 | $(CC) -c $(CFLAGS) $< -o $@ 20 | 21 | #### pre-compiled headers #### 22 | $(HEADERS) : %.gch : %.h 23 | $(CC) -c $(CFLAGS) $< -o $@ 24 | -------------------------------------------------------------------------------- /spec/chess-spec.c: -------------------------------------------------------------------------------- 1 | #include "chess.h" 2 | #include "test_runner.h" 3 | 4 | int new_board_test(void) 5 | { 6 | Square board[8][8]; 7 | new_board(board); 8 | 9 | _assert(board[0][0].color == BLACK); 10 | _assert(board[0][0].piece == ROOK); 11 | 12 | _assert(board[0][3].color == BLACK); 13 | _assert(board[0][3].piece == QUEEN); 14 | 15 | _assert(board[1][6].color == BLACK); 16 | _assert(board[1][6].piece == PAWN); 17 | 18 | _assert(board[5][2].color == BLACK); 19 | _assert(board[5][2].piece == EMPTY); 20 | 21 | _assert(board[6][5].color == WHITE); 22 | _assert(board[6][5].piece == PAWN); 23 | 24 | _assert(board[7][4].color == WHITE); 25 | _assert(board[7][4].piece == KING); 26 | 27 | _assert(board[7][7].color == WHITE); 28 | _assert(board[7][7].piece == ROOK); 29 | return 0; 30 | } 31 | 32 | int piece_value_test(void) 33 | { 34 | _assert(piece_value(PAWN) > piece_value(EMPTY)); 35 | _assert(piece_value(KNIGHT) > piece_value(PAWN)); 36 | _assert(piece_value(BISHOP) == piece_value(KNIGHT)); 37 | _assert(piece_value(ROOK) > piece_value(BISHOP)); 38 | _assert(piece_value(QUEEN) > piece_value(ROOK)); 39 | _assert(piece_value(KING) > piece_value(QUEEN)); 40 | 41 | return 0; 42 | } 43 | int all_tests(void) 44 | { 45 | _run(new_board_test); 46 | _run(piece_value_test); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /spec/global-queue-spec.c: -------------------------------------------------------------------------------- 1 | #include "global-queue.h" 2 | #include "test_runner.h" 3 | 4 | int insert_item_test(void) 5 | { 6 | clear_queue(); 7 | _assert(queue_size() == 0); 8 | insert_item(42); 9 | _assert(front() == 42); 10 | _assert(rear() == 42); 11 | _assert(queue_size() == 1); 12 | 13 | insert_item(10); 14 | _assert(front() == 42); 15 | _assert(rear() == 10); 16 | _assert(queue_size() == 2); 17 | 18 | insert_item(-1); 19 | _assert(front() == 42); 20 | _assert(rear() == -1); 21 | _assert(queue_size() == 3); 22 | 23 | clear_queue(); 24 | return 0; 25 | } 26 | int remove_item_test(void) 27 | { 28 | clear_queue(); 29 | insert_item(42); 30 | _assert(front() == 42); 31 | _assert(queue_size() == 1); 32 | 33 | _assert(remove_item() == 42); 34 | _assert(queue_size() == 0); 35 | _assert(is_empty() == true); 36 | 37 | insert_item(12); 38 | insert_item(13); 39 | insert_item(14); 40 | 41 | _assert(front() == 12); 42 | _assert(rear() == 14); 43 | _assert(queue_size() == 3); 44 | 45 | _assert(remove_item() == 12); 46 | _assert(front() == 13); 47 | _assert(rear() == 14); 48 | _assert(queue_size() == 2); 49 | 50 | _assert(remove_item() == 13); 51 | _assert(front() == 14); 52 | _assert(rear() == 14); 53 | _assert(queue_size() == 1); 54 | 55 | clear_queue(); 56 | return 0; 57 | } 58 | int all_tests(void) 59 | { 60 | _run(insert_item_test); 61 | _run(remove_item_test); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /spec/parts-array-resize-spec.c: -------------------------------------------------------------------------------- 1 | #include "parts.h" 2 | #include "test_runner.h" 3 | #define INITIAL_SIZE 10 4 | 5 | int insert_part_resize_test(void) 6 | { 7 | Parts db = new_db(INITIAL_SIZE); 8 | size_t i; 9 | int rc = 0; 10 | 11 | for (i = 0; i < INITIAL_SIZE - 1; i++) 12 | insert_part(db, set_part(i, "name", 10, 0)); 13 | 14 | rc = insert_part(db, set_part(i, "name", 10, 0)); 15 | 16 | _assert(rc == 0); 17 | _assert(size(db) == INITIAL_SIZE); 18 | 19 | Part p; 20 | int part_number = size(db) + 1; 21 | rc = insert_part(db, set_part(part_number, "unique name", 1020, 0)); 22 | _assert(rc == 0); 23 | _assert(size(db) == INITIAL_SIZE + 1); 24 | p = find_part(db, part_number); 25 | _assert(get_part_number(p) == part_number); 26 | _assert(strcmp(get_part_name(p),"unique name") == 0); 27 | _assert(get_part_on_hand(p) == 1020); 28 | 29 | size_t new_size = INITIAL_SIZE * 2; 30 | for (i = size(db); i < (new_size - 1); i++) 31 | insert_part(db, set_part(i+1, "name", 10, 0)); 32 | 33 | rc = insert_part(db, set_part(i+1, "name", 10, 0)); 34 | 35 | _assert(rc == 0); 36 | _assert(size(db) == new_size); 37 | 38 | part_number = size(db) + 1; 39 | rc = insert_part(db, set_part(part_number, "Fairly unique name", 1021, 0)); 40 | _assert(rc == 0); 41 | _assert(size(db) == 1 + new_size); 42 | p = find_part(db, part_number); 43 | _assert(get_part_number(p) == part_number); 44 | _assert(strcmp(get_part_name(p),"Fairly unique name") == 0); 45 | _assert(get_part_on_hand(p) == 1021); 46 | 47 | destroy_db(db); 48 | 49 | return 0; 50 | } 51 | 52 | int all_tests(void) 53 | { 54 | _run(insert_part_resize_test); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /spec/queue-spec.c: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | #include "test_runner.h" 3 | 4 | int insert_item_test(void) 5 | { 6 | Queue q = create_queue(); 7 | 8 | _assert(depth(q) == 0); 9 | insert_item(q,42); 10 | _assert(front(q) == 42); 11 | _assert(rear(q) == 42); 12 | _assert(depth(q) == 1); 13 | 14 | insert_item(q,10); 15 | _assert(front(q) == 42); 16 | _assert(rear(q) == 10); 17 | _assert(depth(q) == 2); 18 | 19 | insert_item(q,-1); 20 | _assert(front(q) == 42); 21 | _assert(rear(q) == -1); 22 | _assert(depth(q) == 3); 23 | 24 | destroy(q); 25 | return 0; 26 | } 27 | int remove_item_test(void) 28 | { 29 | Queue q = create_queue(); 30 | 31 | insert_item(q,42); 32 | _assert(front(q) == 42); 33 | _assert(depth(q) == 1); 34 | 35 | _assert(remove_item(q) == 42); 36 | _assert(depth(q) == 0); 37 | _assert(is_empty(q) == true); 38 | 39 | insert_item(q,12); 40 | insert_item(q,13); 41 | insert_item(q,14); 42 | 43 | _assert(front(q) == 12); 44 | _assert(rear(q) == 14); 45 | _assert(depth(q) == 3); 46 | 47 | _assert(remove_item(q) == 12); 48 | _assert(front(q) == 13); 49 | _assert(rear(q) == 14); 50 | _assert(depth(q) == 2); 51 | 52 | _assert(remove_item(q) == 13); 53 | _assert(front(q) == 14); 54 | _assert(rear(q) == 14); 55 | _assert(depth(q) == 1); 56 | 57 | destroy(q); 58 | return 0; 59 | } 60 | int all_tests(void) 61 | { 62 | _run(insert_item_test); 63 | _run(remove_item_test); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /src/addfrac.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* addfrac.c (Chapter 3, page 46) */ 11 | /* Adds two fractions */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int num1, denom1, num2, denom2, result_num, result_denom; 18 | 19 | printf("Enter first fraction: "); 20 | scanf("%d/%d", &num1, &denom1); 21 | 22 | printf("Enter second fraction: "); 23 | scanf("%d/%d", &num2, &denom2); 24 | 25 | result_num = num1 * denom2 + num2 * denom1; 26 | result_denom = denom1 * denom2; 27 | printf("The sum is %d/%d\n", result_num, result_denom); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/average.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* average.c (Chapter 9, page 185) */ 11 | /* Computes pairwise averages of three numbers */ 12 | 13 | #include 14 | 15 | double average(double a, double b) 16 | { 17 | return (a + b) / 2; 18 | } 19 | 20 | int main(void) 21 | { 22 | double x, y, z; 23 | 24 | printf("Enter three numbers: "); 25 | scanf("%lf%lf%lf", &x, &y, &z); 26 | printf("Average of %g and %g: %g\n", x, y, average(x, y)); 27 | printf("Average of %g and %g: %g\n", y, z, average(y, z)); 28 | printf("Average of %g and %g: %g\n", x, z, average(x, z)); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/broker.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* broker.c (Chapter 5, page 81) */ 11 | /* Calculates a broker's commission */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | float commission, value; 18 | 19 | printf("Enter value of trade: "); 20 | scanf("%f", &value); 21 | 22 | if (value < 2500.00f) 23 | commission = 30.00f + .017f * value; 24 | else if (value < 6250.00f) 25 | commission = 56.00f + .0066f * value; 26 | else if (value < 20000.00f) 27 | commission = 76.00f + .0034f * value; 28 | else if (value < 50000.00f) 29 | commission = 100.00f + .0022f * value; 30 | else if (value < 500000.00f) 31 | commission = 155.00f + .0011f * value; 32 | else 33 | commission = 255.00f + .0009f * value; 34 | 35 | if (commission < 39.00f) 36 | commission = 39.00f; 37 | 38 | printf("Commission: $%.2f\n", commission); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/canopen.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* canopen.c (Chapter 22, page 547) */ 11 | /* Checks whether a file can be opened for reading */ 12 | 13 | #include 14 | #include 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | FILE *fp; 19 | 20 | if (argc != 2) { 21 | printf("usage: canopen filename\n"); 22 | exit(EXIT_FAILURE); 23 | } 24 | 25 | if ((fp = fopen(argv[1], "r")) == NULL) { 26 | printf("%s can't be opened\n", argv[1]); 27 | exit(EXIT_FAILURE); 28 | } 29 | 30 | printf("%s can be opened\n", argv[1]); 31 | fclose(fp); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /src/celsius.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* celsius.c (Chapter 2, page 24) */ 11 | /* Converts a Fahrenheit temperature to Celsius */ 12 | 13 | #include 14 | 15 | #define FREEZING_PT 32.0f 16 | #define SCALE_FACTOR (5.0f / 9.0f) 17 | 18 | int main(void) 19 | { 20 | float fahrenheit, celsius; 21 | 22 | printf("Enter Fahrenheit temperature: "); 23 | scanf("%f", &fahrenheit); 24 | 25 | celsius = (fahrenheit - FREEZING_PT) * SCALE_FACTOR; 26 | 27 | printf("Celsius equivalent: %.1f\n", celsius); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/checking.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* checking.c (Chapter 6, page 115) */ 11 | /* Balances a checkbook */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int cmd; 18 | float balance = 0.0f, credit, debit; 19 | 20 | printf("*** ACME checkbook-balancing program ***\n"); 21 | printf("Commands: 0=clear, 1=credit, 2=debit, "); 22 | printf("3=balance, 4=exit\n\n"); 23 | 24 | for (;;) { 25 | printf("Enter command: "); 26 | scanf("%d", &cmd); 27 | switch (cmd) { 28 | case 0: 29 | balance = 0.0f; 30 | break; 31 | case 1: 32 | printf("Enter amount of credit: "); 33 | scanf("%f", &credit); 34 | balance += credit; 35 | break; 36 | case 2: 37 | printf("Enter amount of debit: "); 38 | scanf("%f", &debit); 39 | balance -= debit; 40 | break; 41 | case 3: 42 | printf("Current balance: $%.2f\n", balance); 43 | break; 44 | case 4: 45 | return 0; 46 | default: 47 | printf("Commands: 0=clear, 1=credit, 2=debit, "); 48 | printf("3=balance, 4=exit\n\n"); 49 | break; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/countdown.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* countdown.c (Chapter 9, page 186) */ 11 | /* Prints a countdown */ 12 | 13 | #include 14 | 15 | void print_count(int n) 16 | { 17 | printf("T minus %d and counting\n", n); 18 | } 19 | 20 | int main(void) 21 | { 22 | int i; 23 | 24 | for (i = 10; i > 0; --i) 25 | print_count(i); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /src/datetime.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* datetime.c (Chapter 26, page 700) */ 11 | /* Displays the current date and time in three formats */ 12 | 13 | #include 14 | #include 15 | 16 | int main(void) 17 | { 18 | time_t current = time(NULL); 19 | struct tm *ptr; 20 | char date_time[21]; 21 | int hour; 22 | char am_or_pm; 23 | 24 | /* Print date and time in default format */ 25 | puts(ctime(¤t)); 26 | 27 | /* Print date and time, using strftime to format */ 28 | strftime(date_time, sizeof(date_time), 29 | "%m-%d-%Y %I:%M%p\n", localtime(¤t)); 30 | puts(date_time); 31 | 32 | /* Print date and time, using printf to format */ 33 | ptr = localtime(¤t); 34 | hour = ptr->tm_hour; 35 | if (hour <= 11) 36 | am_or_pm = 'a'; 37 | else { 38 | hour -= 12; 39 | am_or_pm = 'p'; 40 | } 41 | if (hour == 0) 42 | hour = 12; 43 | printf("%.2d-%.2d-%d %2d:%.2d%c\n", ptr->tm_mon + 1, 44 | ptr->tm_mday, ptr->tm_year + 1900, hour, 45 | ptr->tm_min, am_or_pm); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /src/deal.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* deal.c (Chapter 8, page 173) */ 11 | /* Deals a random hand of cards */ 12 | 13 | #include /* C99 only */ 14 | #include 15 | #include 16 | #include 17 | 18 | #define NUM_SUITS 4 19 | #define NUM_RANKS 13 20 | 21 | int main(void) 22 | { 23 | bool in_hand[NUM_SUITS][NUM_RANKS] = {false}; 24 | int num_cards, rank, suit; 25 | const char rank_code[] = {'2','3','4','5','6','7','8', 26 | '9','t','j','q','k','a'}; 27 | const char suit_code[] = {'c','d','h','s'}; 28 | 29 | srand((unsigned) time(NULL)); 30 | 31 | printf("Enter number of cards in hand: "); 32 | scanf("%d", &num_cards); 33 | 34 | printf("Your hand:"); 35 | while (num_cards > 0) { 36 | suit = rand() % NUM_SUITS; /* picks a random suit */ 37 | rank = rand() % NUM_RANKS; /* picks a random rank */ 38 | if (!in_hand[suit][rank]) { 39 | in_hand[suit][rank] = true; 40 | num_cards--; 41 | printf(" %c%c", rank_code[rank], suit_code[suit]); 42 | } 43 | } 44 | printf("\n"); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /src/dweight.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* dweight.c (Chapter 2, page 20) */ 11 | /* Computes the dimensional weight of a 12" x 10" x 8" box */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int height, length, width, volume, weight; 18 | 19 | height = 8; 20 | length = 12; 21 | width = 10; 22 | volume = height * length * width; 23 | weight = (volume + 165) / 166; 24 | 25 | printf("Dimensions: %dx%dx%d\n", length, width, height); 26 | printf("Volume (cubic inches): %d\n", volume); 27 | printf("Dimensional weight (pounds): %d\n", weight); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/dweight2.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* dweight2.c (Chapter 2, page 23) */ 11 | /* Computes the dimensional weight of a 12 | box from input provided by the user */ 13 | 14 | #include 15 | 16 | int main(void) 17 | { 18 | int height, length, width, volume, weight; 19 | 20 | printf("Enter height of box: "); 21 | scanf("%d", &height); 22 | printf("Enter length of box: "); 23 | scanf("%d", &length); 24 | printf("Enter width of box: "); 25 | scanf("%d", &width); 26 | volume = height * length * width; 27 | weight = (volume + 165) / 166; 28 | 29 | printf("Volume (cubic inches): %d\n", volume); 30 | printf("Dimensional weight (pounds): %d\n", weight); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /src/fcopy.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* fcopy.c (Chapter 22, page 568) */ 11 | /* Copies a file */ 12 | 13 | #include 14 | #include 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | FILE *source_fp, *dest_fp; 19 | int ch; 20 | 21 | if (argc != 3) { 22 | fprintf(stderr, "usage: fcopy source dest\n"); 23 | exit(EXIT_FAILURE); 24 | } 25 | 26 | if ((source_fp = fopen(argv[1], "rb")) == NULL) { 27 | fprintf(stderr, "Can't open %s\n", argv[1]); 28 | exit(EXIT_FAILURE); 29 | } 30 | 31 | if ((dest_fp = fopen(argv[2], "wb")) == NULL) { 32 | fprintf(stderr, "Can't open %s\n", argv[2]); 33 | fclose(source_fp); 34 | exit(EXIT_FAILURE); 35 | } 36 | 37 | while ((ch = getc(source_fp)) != EOF) 38 | putc(ch, dest_fp); 39 | 40 | fclose(source_fp); 41 | fclose(dest_fp); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/interest.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* interest.c (Chapter 8, page 169) */ 11 | /* Prints a table of compound interest */ 12 | 13 | #include 14 | 15 | #define NUM_RATES ((int) (sizeof(value) / sizeof(value[0]))) 16 | #define INITIAL_BALANCE 100.00 17 | 18 | int main(void) 19 | { 20 | int i, low_rate, num_years, year; 21 | double value[5]; 22 | 23 | printf("Enter interest rate: "); 24 | scanf("%d", &low_rate); 25 | printf("Enter number of years: "); 26 | scanf("%d", &num_years); 27 | 28 | printf("\nYears"); 29 | for (i = 0; i < NUM_RATES; i++) { 30 | printf("%6d%%", low_rate + i); 31 | value[i] = INITIAL_BALANCE; 32 | } 33 | printf("\n"); 34 | 35 | for (year = 1; year <= num_years; year++) { 36 | printf("%3d ", year); 37 | for (i = 0; i < NUM_RATES; i++) { 38 | value[i] += (low_rate + i) / 100.0 * value[i]; 39 | printf("%7.2f", value[i]); 40 | } 41 | printf("\n"); 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/invclear.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* invclear.c (Chapter 22, page 574) */ 11 | /* Modifies a file of part records by setting the quantity 12 | on hand to zero for all records */ 13 | 14 | #include 15 | #include 16 | 17 | #define NAME_LEN 25 18 | #define MAX_PARTS 100 19 | 20 | struct part { 21 | int number; 22 | char name[NAME_LEN+1]; 23 | int on_hand; 24 | } inventory[MAX_PARTS]; 25 | 26 | int num_parts; 27 | 28 | int main(void) 29 | { 30 | FILE *fp; 31 | int i; 32 | 33 | if ((fp = fopen("inventory.dat", "rb+")) == NULL) { 34 | fprintf(stderr, "Can't open inventory file\n"); 35 | exit(EXIT_FAILURE); 36 | } 37 | 38 | num_parts = fread(inventory, sizeof(struct part), 39 | MAX_PARTS, fp); 40 | 41 | for (i = 0; i < num_parts; i++) 42 | inventory[i].on_hand = 0; 43 | 44 | rewind(fp); 45 | fwrite(inventory, sizeof(struct part), num_parts, fp); 46 | fclose(fp); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /src/justify.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* justify.c (Chapter 15, page 363) */ 11 | /* Formats a file of text */ 12 | 13 | #include 14 | #include "line.h" 15 | #include "word.h" 16 | 17 | #define MAX_WORD_LEN 20 18 | 19 | int main(void) 20 | { 21 | char word[MAX_WORD_LEN+2]; 22 | int word_len; 23 | 24 | clear_line(); 25 | for (;;) { 26 | read_word(word, MAX_WORD_LEN+1); 27 | word_len = strlen(word); 28 | if (word_len == 0) { 29 | flush_line(); 30 | return 0; 31 | } 32 | if (word_len > MAX_WORD_LEN) 33 | word[MAX_WORD_LEN] = '*'; 34 | if (word_len + 1 > space_remaining()) { 35 | write_line(); 36 | clear_line(); 37 | } 38 | add_word(word); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/length.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* length.c (Chapter 7, page 142) */ 11 | /* Determines the length of a message */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | char ch; 18 | int len = 0; 19 | 20 | printf("Enter a message: "); 21 | ch = getchar(); 22 | while (ch != '\n') { 23 | len++; 24 | ch = getchar(); 25 | } 26 | printf("Your message was %d character(s) long.\n", len); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /src/length2.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* length2.c (Chapter 7, page 142) */ 11 | /* Determines the length of a message */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int len = 0; 18 | 19 | printf("Enter a message: "); 20 | while (getchar() != '\n') 21 | len++; 22 | printf("Your message was %d character(s) long.\n", len); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /src/maxmin.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* maxmin.c (Chapter 11, page 250) */ 11 | /* Finds the largest and smallest elements in an array */ 12 | 13 | #include 14 | 15 | #define N 10 16 | 17 | void max_min(int a[], int n, int *max, int *min); 18 | 19 | int main(void) 20 | { 21 | int b[N], i, big, small; 22 | 23 | printf("Enter %d numbers: ", N); 24 | for (i = 0; i < N; i++) 25 | scanf("%d", &b[i]); 26 | 27 | max_min(b, N, &big, &small); 28 | 29 | printf("Largest: %d\n", big); 30 | printf("Smallest: %d\n", small); 31 | 32 | return 0; 33 | } 34 | 35 | void max_min(int a[], int n, int *max, int *min) 36 | { 37 | int i; 38 | 39 | *max = *min = a[0]; 40 | for (i = 1; i < n; i++) { 41 | if (a[i] > *max) 42 | *max = a[i]; 43 | else if (a[i] < *min) 44 | *min = a[i]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/numdigits.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* numdigits.c (Chapter 6, page 105) */ 11 | /* Calculates the number of digits in an integer */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int digits = 0, n; 18 | 19 | printf("Enter a nonnegative integer: "); 20 | scanf("%d", &n); 21 | 22 | do { 23 | n /= 10; 24 | digits++; 25 | } while (n > 0); 26 | 27 | printf("The number has %d digit(s).\n", digits); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/planet.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* planet.c (Chapter 13, page 304) */ 11 | /* Checks planet names */ 12 | 13 | #include 14 | #include 15 | 16 | #define NUM_PLANETS 9 17 | 18 | int main(int argc, char *argv[]) 19 | { 20 | char *planets[] = {"Mercury", "Venus", "Earth", 21 | "Mars", "Jupiter", "Saturn", 22 | "Uranus", "Neptune", "Pluto"}; 23 | int i, j; 24 | 25 | for (i = 1; i < argc; i++) { 26 | for (j = 0; j < NUM_PLANETS; j++) 27 | if (strcmp(argv[i], planets[j]) == 0) { 28 | printf("%s is planet %d\n", argv[i], j + 1); 29 | break; 30 | } 31 | if (j == NUM_PLANETS) 32 | printf("%s is not a planet\n", argv[i]); 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/prime.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* prime.c (Chapter 9, page 190) */ 11 | /* Tests whether a number is prime */ 12 | 13 | #include /* C99 only */ 14 | #include 15 | 16 | bool is_prime(int n) 17 | { 18 | int divisor; 19 | 20 | if (n <= 1) 21 | return false; 22 | for (divisor = 2; divisor * divisor <= n; divisor++) 23 | if (n % divisor == 0) 24 | return false; 25 | return true; 26 | } 27 | 28 | int main(void) 29 | { 30 | int n; 31 | 32 | printf("Enter a number: "); 33 | scanf("%d", &n); 34 | if (is_prime(n)) 35 | printf("Prime\n"); 36 | else 37 | printf("Not prime\n"); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/pun.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* pun.c (Chapter 2, page 10) */ 11 | 12 | #include 13 | 14 | int main(void) 15 | { 16 | printf("To C, or not to C: that is the question.\n"); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /src/pun2.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* pun2.c (Chapter 9, page 187) */ 11 | /* Prints a bad pun */ 12 | 13 | #include 14 | 15 | void print_pun(void) 16 | { 17 | printf("To C, or not to C: that is the question.\n"); 18 | } 19 | 20 | int main(void) 21 | { 22 | print_pun(); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/quadratic.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* quadratic.c (Chapter 27, page 723) */ 11 | /* Finds the roots of the equation 5x**2 + 2x + 1 = 0 */ 12 | 13 | #include 14 | #include 15 | 16 | int main(void) 17 | { 18 | double a = 5, b = 2, c = 1; 19 | double complex discriminant_sqrt = csqrt(b * b - 4 * a * c); 20 | double complex root1 = (-b + discriminant_sqrt) / (2 * a); 21 | double complex root2 = (-b - discriminant_sqrt) / (2 * a); 22 | 23 | printf("root1 = %g + %gi\n", creal(root1), cimag(root1)); 24 | printf("root2 = %g + %gi\n", creal(root2), cimag(root2)); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/readline.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.c (Chapter 16, page 395) */ 11 | 12 | #include 13 | #include 14 | #include "readline.h" 15 | 16 | int read_line(char str[], int n) 17 | { 18 | int ch, i = 0; 19 | 20 | while (isspace(ch = getchar())) 21 | ; 22 | while (ch != '\n' && ch != EOF) { 23 | if (i < n) 24 | str[i++] = ch; 25 | ch = getchar(); 26 | } 27 | str[i] = '\0'; 28 | return i; 29 | } 30 | -------------------------------------------------------------------------------- /src/readline.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* readline.h (Chapter 16, page 395) */ 11 | 12 | #ifndef READLINE_H 13 | #define READLINE_H 14 | 15 | /********************************************************** 16 | * read_line: Skips leading white-space characters, then * 17 | * reads the remainder of the input line and * 18 | * stores it in str. Truncates the line if its * 19 | * length exceeds n. Returns the number of * 20 | * characters stored. * 21 | **********************************************************/ 22 | int read_line(char str[], int n); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/repdigit.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* repdigit.c (Chapter 8, page 166) */ 11 | /* Checks numbers for repeated digits */ 12 | 13 | #include /* C99 only */ 14 | #include 15 | 16 | int main(void) 17 | { 18 | bool digit_seen[10] = {false}; 19 | int digit; 20 | long n; 21 | 22 | printf("Enter a number: "); 23 | scanf("%ld", &n); 24 | 25 | while (n > 0) { 26 | digit = n % 10; 27 | if (digit_seen[digit]) 28 | break; 29 | digit_seen[digit] = true; 30 | n /= 10; 31 | } 32 | 33 | if (n > 0) 34 | printf("Repeated digit\n"); 35 | else 36 | printf("No repeated digit\n"); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /src/reverse.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* reverse.c (Chapter 8, page 164) */ 11 | /* Reverses a series of numbers */ 12 | 13 | #include 14 | 15 | #define N 10 16 | 17 | int main(void) 18 | { 19 | int a[N], i; 20 | 21 | printf("Enter %d numbers: ", N); 22 | for (i = 0; i < N; i++) 23 | scanf("%d", &a[i]); 24 | 25 | printf("In reverse order:"); 26 | for (i = N - 1; i >= 0; i--) 27 | printf(" %d", a[i]); 28 | printf("\n"); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/reverse2.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* reverse2.c (Chapter 8, page 174) */ 11 | /* Reverses a series of numbers using a variable-length 12 | array - C99 only */ 13 | 14 | #include 15 | 16 | int main(void) 17 | { 18 | int i, n; 19 | 20 | printf("How many numbers do you want to reverse? "); 21 | scanf("%d", &n); 22 | 23 | int a[n]; /* C99 only - length of array depends on n */ 24 | 25 | printf("Enter %d numbers: ", n); 26 | for (i = 0; i < n; i++) 27 | scanf("%d", &a[i]); 28 | 29 | printf("In reverse order:"); 30 | for (i = n - 1; i >= 0; i--) 31 | printf(" %d", a[i]); 32 | printf("\n"); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /src/reverse3.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* reverse3.c (Chapter 12, page 264) */ 11 | /* Reverses a series of numbers (pointer version) */ 12 | 13 | #include 14 | 15 | #define N 10 16 | 17 | int main(void) 18 | { 19 | int a[N], *p; 20 | 21 | printf("Enter %d numbers: ", N); 22 | for (p = a; p < a + N; p++) 23 | scanf("%d", p); 24 | 25 | printf("In reverse order:"); 26 | for (p = a + N - 1; p >= a; p--) 27 | printf(" %d", *p); 28 | printf("\n"); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/square.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* square.c (Chapter 6, page 102) */ 11 | /* Prints a table of squares using a while statement */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int i, n; 18 | 19 | printf("This program prints a table of squares.\n"); 20 | printf("Enter number of entries in table: "); 21 | scanf("%d", &n); 22 | 23 | i = 1; 24 | while (i <= n) { 25 | printf("%10d%10d\n", i, i * i); 26 | i++; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/square2.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* square2.c (Chapter 6, page 110) */ 11 | /* Prints a table of squares using a for statement */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int i, n; 18 | 19 | printf("This program prints a table of squares.\n"); 20 | printf("Enter number of entries in table: "); 21 | scanf("%d", &n); 22 | 23 | for (i = 1; i <= n; i++) 24 | printf("%10d%10d\n", i, i * i); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/square3.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* square3.c (Chapter 6, page 110) */ 11 | /* Prints a table of squares using an odd method */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int i, n, odd, square; 18 | 19 | printf("This program prints a table of squares.\n"); 20 | printf("Enter number of entries in table: "); 21 | scanf("%d", &n); 22 | 23 | i = 1; 24 | odd = 3; 25 | for (square = 1; i <= n; odd += 2) { 26 | printf("%10d%10d\n", i, square); 27 | ++i; 28 | square += odd; 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /src/stack.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stack.h (Chapter 19, page 488) */ 11 | 12 | #ifndef STACK_H 13 | #define STACK_H 14 | 15 | #include /* C99 only */ 16 | 17 | void make_empty(void); 18 | bool is_empty(void); 19 | bool is_full(void); 20 | void push(int i); 21 | int pop(void); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/stack1.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stack1.c (Chapter 19, page 488) */ 11 | 12 | #include 13 | #include 14 | #include "stack.h" 15 | 16 | #define STACK_SIZE 100 17 | 18 | static int contents[STACK_SIZE]; 19 | static int top = 0; 20 | 21 | static void terminate(const char *message) 22 | { 23 | printf("%s\n", message); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | void make_empty(void) 28 | { 29 | top = 0; 30 | } 31 | 32 | bool is_empty(void) 33 | { 34 | return top == 0; 35 | } 36 | 37 | bool is_full(void) 38 | { 39 | return top == STACK_SIZE; 40 | } 41 | 42 | void push(int i) 43 | { 44 | if (is_full()) 45 | terminate("Error in push: stack is full."); 46 | contents[top++] = i; 47 | } 48 | 49 | int pop(void) 50 | { 51 | if (is_empty()) 52 | terminate("Error in pop: stack is empty."); 53 | return contents[--top]; 54 | } 55 | -------------------------------------------------------------------------------- /src/stack2.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stack2.c (Chapter 19, page 489) */ 11 | 12 | #include 13 | #include 14 | #include "stack.h" 15 | 16 | struct node { 17 | int data; 18 | struct node *next; 19 | }; 20 | 21 | static struct node *top = NULL; 22 | 23 | static void terminate(const char *message) 24 | { 25 | printf("%s\n", message); 26 | exit(EXIT_FAILURE); 27 | } 28 | 29 | void make_empty(void) 30 | { 31 | while (!is_empty()) 32 | pop(); 33 | } 34 | 35 | bool is_empty(void) 36 | { 37 | return top == NULL; 38 | } 39 | 40 | bool is_full(void) 41 | { 42 | return false; 43 | } 44 | 45 | void push(int i) 46 | { 47 | struct node *new_node = malloc(sizeof(struct node)); 48 | if (new_node == NULL) 49 | terminate("Error in push: stack is full."); 50 | 51 | new_node->data = i; 52 | new_node->next = top; 53 | top = new_node; 54 | } 55 | 56 | int pop(void) 57 | { 58 | struct node *old_top; 59 | int i; 60 | 61 | if (is_empty()) 62 | terminate("Error in pop: stack is empty."); 63 | 64 | old_top = top; 65 | i = top->data; 66 | top = top->next; 67 | free(old_top); 68 | return i; 69 | } 70 | -------------------------------------------------------------------------------- /src/stackADT.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stackADT.c (Chapter 19, page 495) */ 11 | 12 | #include 13 | #include 14 | #include "stackADT.h" 15 | 16 | #define STACK_SIZE 100 17 | 18 | struct stack_type { 19 | int contents[STACK_SIZE]; 20 | int top; 21 | }; 22 | 23 | static void terminate(const char *message) 24 | { 25 | printf("%s\n", message); 26 | exit(EXIT_FAILURE); 27 | } 28 | 29 | Stack create(void) 30 | { 31 | Stack s = malloc(sizeof(struct stack_type)); 32 | if (s == NULL) 33 | terminate("Error in create: stack could not be created."); 34 | s->top = 0; 35 | return s; 36 | } 37 | 38 | void destroy(Stack s) 39 | { 40 | free(s); 41 | } 42 | 43 | void make_empty(Stack s) 44 | { 45 | s->top = 0; 46 | } 47 | 48 | bool is_empty(Stack s) 49 | { 50 | return s->top == 0; 51 | } 52 | 53 | bool is_full(Stack s) 54 | { 55 | return s->top == STACK_SIZE; 56 | } 57 | 58 | void push(Stack s, int i) 59 | { 60 | if (is_full(s)) 61 | terminate("Error in push: stack is full."); 62 | s->contents[s->top++] = i; 63 | } 64 | 65 | int pop(Stack s) 66 | { 67 | if (is_empty(s)) 68 | terminate("Error in pop: stack is empty."); 69 | return s->contents[--s->top]; 70 | } 71 | -------------------------------------------------------------------------------- /src/stackADT.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stackADT.h (Chapter 19, page 496) */ 11 | 12 | #ifndef STACKADT_H 13 | #define STACKADT_H 14 | 15 | #include /* C99 only */ 16 | 17 | typedef int Item; 18 | 19 | typedef struct stack_type *Stack; 20 | 21 | Stack create(void); 22 | void destroy(Stack s); 23 | void make_empty(Stack s); 24 | bool is_empty(Stack s); 25 | bool is_full(Stack s); 26 | void push(Stack s, Item i); 27 | Item pop(Stack s); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/stackADT2.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stackADT2.h (Chapter 19, page 498) */ 11 | 12 | #ifndef STACKADT_H 13 | #define STACKADT_H 14 | 15 | #include /* C99 only */ 16 | 17 | typedef int Item; 18 | 19 | typedef struct stack_type *Stack; 20 | 21 | Stack create(int size); 22 | void destroy(Stack s); 23 | void make_empty(Stack s); 24 | bool is_empty(Stack s); 25 | bool is_full(Stack s); 26 | void push(Stack s, Item i); 27 | Item pop(Stack s); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/stackclient.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* stackclient.c (Chapter 19, page 494) */ 11 | 12 | #include 13 | #include "stackADT.h" 14 | 15 | int main(void) 16 | { 17 | Stack s1, s2; 18 | int n; 19 | 20 | s1 = create(); 21 | s2 = create(); 22 | 23 | push(s1, 1); 24 | push(s1, 2); 25 | 26 | n = pop(s1); 27 | printf("Popped %d from s1\n", n); 28 | push(s2, n); 29 | n = pop(s1); 30 | printf("Popped %d from s1\n", n); 31 | push(s2, n); 32 | 33 | destroy(s1); 34 | 35 | while (!is_empty(s2)) 36 | printf("Popped %d from s2\n", pop(s2)); 37 | 38 | push(s2, 3); 39 | make_empty(s2); 40 | if (is_empty(s2)) 41 | printf("s2 is empty\n"); 42 | else 43 | printf("s2 is not empty\n"); 44 | 45 | destroy(s2); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /src/sum.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* sum.c (Chapter 6, page 103) */ 11 | /* Sums a series of numbers */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int n, sum = 0; 18 | 19 | printf("This program sums a series of integers.\n"); 20 | printf("Enter integers (0 to terminate): "); 21 | 22 | scanf("%d", &n); 23 | while (n != 0) { 24 | sum += n; 25 | scanf("%d", &n); 26 | } 27 | printf("The sum is: %d\n", sum); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/sum2.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* sum2.c (Chapter 7, page 131) */ 11 | /* Sums a series of numbers (using long variables) */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | long n, sum = 0; 18 | 19 | printf("This program sums a series of integers.\n"); 20 | printf("Enter integers (0 to terminate): "); 21 | 22 | scanf("%ld", &n); 23 | while (n != 0) { 24 | sum += n; 25 | scanf("%ld", &n); 26 | } 27 | printf("The sum is: %ld\n", sum); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/tcasemap.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* tcasemap.c (Chapter 23, page 615) */ 11 | /* Tests the case-mapping functions */ 12 | 13 | #include 14 | #include 15 | 16 | int main(void) 17 | { 18 | char *p; 19 | 20 | for (p = "aA0!"; *p != '\0'; p++) { 21 | printf("tolower('%c') is '%c'; ", *p, tolower(*p)); 22 | printf("toupper('%c') is '%c'\n", *p, toupper(*p)); 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /src/tclassify.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* tclassify.c (Chapter 23, page 613) */ 11 | /* Tests the character-classification functions */ 12 | 13 | #include 14 | #include 15 | 16 | #define TEST(f) printf(" %c ", f(*p) ? 'x' : ' ') 17 | 18 | int main(void) 19 | { 20 | char *p; 21 | 22 | printf(" alnum cntrl graph print" 23 | " space xdigit\n" 24 | " alpha digit lower punct" 25 | " upper\n"); 26 | 27 | for (p = "azAZ0 !\t"; *p != '\0'; p++) { 28 | if (iscntrl(*p)) 29 | printf("\\x%02x:", *p); 30 | else 31 | printf(" %c:", *p); 32 | TEST(isalnum); 33 | TEST(isalpha); 34 | TEST(iscntrl); 35 | TEST(isdigit); 36 | TEST(isgraph); 37 | TEST(islower); 38 | TEST(isprint); 39 | TEST(ispunct); 40 | TEST(isspace); 41 | TEST(isupper); 42 | TEST(isxdigit); 43 | printf("\n"); 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /src/tprintf.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* tprintf.c (Chapter 3, page 40) */ 11 | /* Prints int and float values in various formats */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int i; 18 | float x; 19 | 20 | i = 40; 21 | x = 839.21f; 22 | 23 | printf("|%d|%5d|%-5d|%5.3d|\n", i, i, i, i); 24 | printf("|%10.3f|%10.3e|%-10g|\n", x, x, x); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/trand.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* trand.c (Chapter 26, page 687) */ 11 | /* Tests the pseudo-random sequence generation functions */ 12 | 13 | #include 14 | #include 15 | 16 | int main(void) 17 | { 18 | int i, seed; 19 | 20 | printf("This program displays the first five values of " 21 | "rand.\n"); 22 | 23 | for (;;) { 24 | for (i = 0; i < 5; i++) 25 | printf("%d ", rand()); 26 | printf("\n\n"); 27 | printf("Enter new seed value (0 to terminate): "); 28 | scanf("%d", &seed); 29 | if (seed == 0) 30 | break; 31 | srand(seed); 32 | } 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /src/tsetjmp.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* tsetjmp.c (Chapter 24, page 636) */ 11 | /* Tests setjmp/longjmp */ 12 | 13 | #include 14 | #include 15 | 16 | jmp_buf env; 17 | 18 | void f1(void); 19 | void f2(void); 20 | 21 | int main(void) 22 | { 23 | if (setjmp(env) == 0) 24 | printf("setjmp returned 0\n"); 25 | else { 26 | printf("Program terminates: longjmp called\n"); 27 | return 0; 28 | } 29 | 30 | f1(); 31 | printf("Program terminates normally\n"); 32 | return 0; 33 | } 34 | 35 | void f1(void) 36 | { 37 | printf("f1 begins\n"); 38 | f2(); 39 | printf("f1 returns\n"); 40 | } 41 | 42 | void f2(void) 43 | { 44 | printf("f2 begins\n"); 45 | longjmp(env, 1); 46 | printf("f2 returns\n"); 47 | } 48 | -------------------------------------------------------------------------------- /src/tsignal.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* tsignal.c (Chapter 24, page 634) */ 11 | /* Tests signals */ 12 | 13 | #include 14 | #include 15 | 16 | void handler(int sig); 17 | void raise_sig(void); 18 | 19 | int main(void) 20 | { 21 | void (*orig_handler)(int); 22 | 23 | printf("Installing handler for signal %d\n", SIGINT); 24 | orig_handler = signal(SIGINT, handler); 25 | raise_sig(); 26 | 27 | printf("Changing handler to SIG_IGN\n"); 28 | signal(SIGINT, SIG_IGN); 29 | raise_sig(); 30 | 31 | printf("Restoring original handler\n"); 32 | signal(SIGINT, orig_handler); 33 | raise_sig(); 34 | 35 | printf("Program terminates normally\n"); 36 | return 0; 37 | } 38 | 39 | void handler(int sig) 40 | { 41 | printf("Handler called for signal %d\n", sig); 42 | } 43 | 44 | void raise_sig(void) 45 | { 46 | raise(SIGINT); 47 | } 48 | -------------------------------------------------------------------------------- /src/upc.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* upc.c (Chapter 4, page 57) */ 11 | /* Computes a Universal Product Code check digit */ 12 | 13 | #include 14 | 15 | int main(void) 16 | { 17 | int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, 18 | first_sum, second_sum, total; 19 | 20 | printf("Enter the first (single) digit: "); 21 | scanf("%1d", &d); 22 | printf("Enter first group of five digits: "); 23 | scanf("%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5); 24 | printf("Enter second group of five digits: "); 25 | scanf("%1d%1d%1d%1d%1d", &j1, &j2, &j3, &j4, &j5); 26 | 27 | first_sum = d + i2 + i4 + j1 + j3 + j5; 28 | second_sum = i1 + i3 + i5 + j2 + j4; 29 | total = 3 * first_sum + second_sum; 30 | 31 | printf("Check digit: %d\n", 9 - ((total - 1) % 10)); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/word.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* word.c (Chapter 15, page 363) */ 11 | 12 | #include 13 | #include "word.h" 14 | 15 | int read_char(void) 16 | { 17 | int ch = getchar(); 18 | 19 | if (ch == '\n' || ch == '\t') 20 | return ' '; 21 | return ch; 22 | } 23 | 24 | void read_word(char *word, int len) 25 | { 26 | int ch, pos = 0; 27 | 28 | while ((ch = read_char()) == ' ') 29 | ; 30 | while (ch != ' ' && ch != EOF) { 31 | if (pos < len) 32 | word[pos++] = ch; 33 | ch = read_char(); 34 | } 35 | word[pos] = '\0'; 36 | } 37 | -------------------------------------------------------------------------------- /src/word.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* word.h (Chapter 15, page 361) */ 11 | 12 | #ifndef WORD_H 13 | #define WORD_H 14 | 15 | /********************************************************** 16 | * read_word: Reads the next word from the input and * 17 | * stores it in word. Makes word empty if no * 18 | * word could be read because of end-of-file. * 19 | * Truncates the word if its length exceeds * 20 | * len. * 21 | **********************************************************/ 22 | void read_word(char *word, int len); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/xor.c: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * From C PROGRAMMING: A MODERN APPROACH, Second Edition * 3 | * By K. N. King * 4 | * Copyright (c) 2008, 1996 W. W. Norton & Company, Inc. * 5 | * All rights reserved. * 6 | * This program may be freely distributed for class use, * 7 | * provided that this copyright notice is retained. * 8 | *********************************************************/ 9 | 10 | /* xor.c (Chapter 20, page 515) */ 11 | /* Performs XOR encryption */ 12 | 13 | #include 14 | #include 15 | 16 | #define KEY '&' 17 | 18 | int main(void) 19 | { 20 | int orig_char, new_char; 21 | 22 | while ((orig_char = getchar()) != EOF) { 23 | new_char = orig_char ^ KEY; 24 | if (isprint(orig_char) && isprint(new_char)) 25 | putchar(new_char); 26 | else 27 | putchar(orig_char); 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /weird/compound-literal-string-parameter-clang-bug.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | * $ clang --version 5 | * clang version 3.1 (branches/release_31) 6 | * Target: x86_64-apple-darwin10.8.0 7 | * Thread model: posix 8 | */ 9 | 10 | 11 | /* 12 | * output without call to printf from within main: 13 | * 14 | * $ weird/compound-literal-string-parameter-clang-bug | xxd 15 | * 0000000: 0d0a 20e7 bf5f ff7f .. .._.. 16 | * $ weird/compound-literal-string-parameter-clang-bug | wc 17 | * 1 1 8 18 | */ 19 | 20 | /* works fine compiled with i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 */ 21 | void write_dos_newline() 22 | { 23 | printf("%s", (char[2]){0x0D, 0x0A}); 24 | } 25 | 26 | 27 | int main(void) 28 | { 29 | /* call from main works as expected */ 30 | printf("%s", (char[2]){0x0D, 0x0A}); 31 | /* call via function appends 6 bytes of junk */ 32 | write_dos_newline(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /weird/malloc-gives-a-million-for-request-of-10.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int test_1(void) 7 | { 8 | char *s; 9 | int i; 10 | 11 | assert(sizeof(char) == 1); 12 | 13 | s = malloc(10); 14 | assert(s != NULL); 15 | 16 | s[10] = 'A'; 17 | assert(s[10] == 'A'); 18 | 19 | /* Threshhold on my machine: note, binary MB, 2**20, == 1048576 */ 20 | i = 1048447; /* works */ 21 | i = 1048448; /* segfualts */ 22 | 23 | i = 1000000; 24 | s[i] = 'A'; 25 | assert(s[i] == 'A'); 26 | 27 | free(s); 28 | 29 | return 0; 30 | } 31 | 32 | int test_2(void) 33 | { 34 | char *s; 35 | int i = 0; 36 | 37 | s = malloc(10); 38 | assert(s != NULL); 39 | 40 | for (;i < 100000; i++) 41 | strcat(s, "0123456789"); 42 | 43 | puts(s); 44 | 45 | free(s); 46 | 47 | return 0; 48 | } 49 | 50 | int main(void) 51 | { 52 | assert(test_1() == 0); 53 | assert(test_2() == 0); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /weird/scanf-clobbers-adjacent-var.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int play_game(void) 5 | { 6 | return rand() % 2; 7 | } 8 | 9 | int main(void) 10 | { 11 | char response; 12 | int wins, losses; 13 | wins = losses = 0; 14 | 15 | do { 16 | if (play_game()) { 17 | printf("Win!\n"); 18 | wins++; 19 | } else { 20 | printf("Lose.\n"); 21 | losses++; 22 | } 23 | 24 | printf("Play again? "); 25 | /* 26 | * this format string (" %c") works, and causes no problems 27 | */ 28 | /*scanf(" %c", &response);*/ 29 | 30 | /* 31 | * with this format string, (" %s") 32 | * the value of 'losses' gets reset to 0 33 | */ 34 | scanf(" %s", &response); 35 | } while ( response == 'y' || response == 'Y'); 36 | 37 | printf("Wins: %d\tLosses: %d\n", wins, losses); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /weird/scanf-clobbers-adjacent-var.gdb.log: -------------------------------------------------------------------------------- 1 | 2 | Reading symbols from /home/tim/c/c-programming/weird/scanf-clobbers-adjacent-var...done. 3 | (gdb) br 13 4 | Breakpoint 1 at 0x400621: file weird/scanf-clobbers-adjacent-var.c, line 13. 5 | (gdb) r 6 | Starting program: /home/tim/c/c-programming/weird/scanf-clobbers-adjacent-var 7 | 8 | Breakpoint 1, main () at weird/scanf-clobbers-adjacent-var.c:13 9 | 13 if (play_game()) { 10 | (gdb) p &losses 11 | $1 = (int *) 0x7fffffffe228 12 | (gdb) p &response 13 | $2 = 0x7fffffffe227 "" 14 | (gdb) n 15 | 14 printf("Win!\n"); 16 | (gdb) n 17 | 15 wins++; 18 | (gdb) n 19 | 21 printf("Play again? "); 20 | (gdb) n 21 | 23 scanf(" %s", &response); 22 | (gdb) n 23 | 24 } while ( response == 'y' || response == 'Y'); 24 | (gdb) c 25 | Continuing. 26 | 27 | Breakpoint 1, main () at weird/scanf-clobbers-adjacent-var.c:13 28 | 13 if (play_game()) { 29 | (gdb) n 30 | 17 printf("Lose.\n"); 31 | (gdb) n 32 | 18 losses++; 33 | (gdb) n 34 | 21 printf("Play again? "); 35 | (gdb) p losses 36 | $3 = 1 37 | (gdb) n 38 | 23 scanf(" %s", &response); 39 | (gdb) n 40 | 24 } while ( response == 'y' || response == 'Y'); 41 | (gdb) p losses 42 | $4 = 0 43 | (gdb) c 44 | Continuing. 45 | Win! 46 | Play again? Lose. 47 | Play again? Wins: 1 Losses: 0 48 | [Inferior 1 (process 12479) exited normally] 49 | (gdb) q 50 | --------------------------------------------------------------------------------