summaryrefslogtreecommitdiff
path: root/usr.bin/learn/lib/C
diff options
context:
space:
mode:
authorIan Darwin <ian@cvs.openbsd.org>1998-09-28 16:01:29 +0000
committerIan Darwin <ian@cvs.openbsd.org>1998-09-28 16:01:29 +0000
commite9be7faad5fbf61edcad3700142615e315e407bc (patch)
tree5f3febafdfca4e38b83cbc129c87aefdece9ae70 /usr.bin/learn/lib/C
parent0436a5b6c19a613da918536b89a49cbcb38a2e4e (diff)
import BTL learn(1) lessons/C
Diffstat (limited to 'usr.bin/learn/lib/C')
-rw-r--r--usr.bin/learn/lib/C/L02
-rw-r--r--usr.bin/learn/lib/C/L0.1a19
-rw-r--r--usr.bin/learn/lib/C/L1.1a23
-rw-r--r--usr.bin/learn/lib/C/L1.1b31
-rw-r--r--usr.bin/learn/lib/C/L1.1c18
-rw-r--r--usr.bin/learn/lib/C/L1.1d33
-rw-r--r--usr.bin/learn/lib/C/L1.1e14
-rw-r--r--usr.bin/learn/lib/C/L1.1f19
-rw-r--r--usr.bin/learn/lib/C/L1015
-rw-r--r--usr.bin/learn/lib/C/L11.1a35
-rw-r--r--usr.bin/learn/lib/C/L11.2a29
-rw-r--r--usr.bin/learn/lib/C/L12.1a35
-rw-r--r--usr.bin/learn/lib/C/L12.1b60
-rw-r--r--usr.bin/learn/lib/C/L13.1a39
-rw-r--r--usr.bin/learn/lib/C/L14.1a38
-rw-r--r--usr.bin/learn/lib/C/L14.2a26
-rw-r--r--usr.bin/learn/lib/C/L14.2b41
-rw-r--r--usr.bin/learn/lib/C/L15.1a33
-rw-r--r--usr.bin/learn/lib/C/L15.1b40
-rw-r--r--usr.bin/learn/lib/C/L16.2a54
-rw-r--r--usr.bin/learn/lib/C/L16.2b40
-rw-r--r--usr.bin/learn/lib/C/L16.2c67
-rw-r--r--usr.bin/learn/lib/C/L17.1a71
-rw-r--r--usr.bin/learn/lib/C/L17.1c50
-rw-r--r--usr.bin/learn/lib/C/L18.1a49
-rw-r--r--usr.bin/learn/lib/C/L19.1a29
-rw-r--r--usr.bin/learn/lib/C/L2.1a55
-rw-r--r--usr.bin/learn/lib/C/L2.1b21
-rw-r--r--usr.bin/learn/lib/C/L2.1c16
-rw-r--r--usr.bin/learn/lib/C/L2.1d15
-rw-r--r--usr.bin/learn/lib/C/L2.1e19
-rw-r--r--usr.bin/learn/lib/C/L20.1a105
-rw-r--r--usr.bin/learn/lib/C/L3.1a56
-rw-r--r--usr.bin/learn/lib/C/L3.1b14
-rw-r--r--usr.bin/learn/lib/C/L30.1a45
-rw-r--r--usr.bin/learn/lib/C/L31.1a48
-rw-r--r--usr.bin/learn/lib/C/L32.1a50
-rw-r--r--usr.bin/learn/lib/C/L33.1a23
-rw-r--r--usr.bin/learn/lib/C/L35.1a35
-rw-r--r--usr.bin/learn/lib/C/L37.1a57
-rw-r--r--usr.bin/learn/lib/C/L4.1a10
-rw-r--r--usr.bin/learn/lib/C/L40.1a56
-rw-r--r--usr.bin/learn/lib/C/L41.1a67
-rw-r--r--usr.bin/learn/lib/C/L42.1a57
-rw-r--r--usr.bin/learn/lib/C/L43.1a70
-rw-r--r--usr.bin/learn/lib/C/L43.1b67
-rw-r--r--usr.bin/learn/lib/C/L5.1a26
-rw-r--r--usr.bin/learn/lib/C/L5.1b25
-rw-r--r--usr.bin/learn/lib/C/L5.1c31
-rw-r--r--usr.bin/learn/lib/C/L5.1d48
-rw-r--r--usr.bin/learn/lib/C/L5.1e31
-rw-r--r--usr.bin/learn/lib/C/L5.1f17
-rw-r--r--usr.bin/learn/lib/C/L5.1g38
-rw-r--r--usr.bin/learn/lib/C/L5.2a27
-rw-r--r--usr.bin/learn/lib/C/L5.2b28
-rw-r--r--usr.bin/learn/lib/C/L5.2e58
-rw-r--r--usr.bin/learn/lib/C/L5.3e28
-rw-r--r--usr.bin/learn/lib/C/L50.1a145
-rw-r--r--usr.bin/learn/lib/C/L9.1a33
-rw-r--r--usr.bin/learn/lib/C/getline.c16
-rw-r--r--usr.bin/learn/lib/C/getnum.c13
61 files changed, 2360 insertions, 0 deletions
diff --git a/usr.bin/learn/lib/C/L0 b/usr.bin/learn/lib/C/L0
new file mode 100644
index 00000000000..bab7601e708
--- /dev/null
+++ b/usr.bin/learn/lib/C/L0
@@ -0,0 +1,2 @@
+#next
+0.1a 10
diff --git a/usr.bin/learn/lib/C/L0.1a b/usr.bin/learn/lib/C/L0.1a
new file mode 100644
index 00000000000..6082ae50f2d
--- /dev/null
+++ b/usr.bin/learn/lib/C/L0.1a
@@ -0,0 +1,19 @@
+#print
+This script is loosely based on the material in
+"The C Programming Language", by Brian Kernighan
+and Dennis Ritchie (Prentice-Hall, 1978).
+You may find it helpful to have that at hand.
+Some of the lessons will indicate
+the section that they are based on.
+
+Do you have a copy at hand? Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+Fine.
+#fail
+It might help, but it's not critical.
+#log
+#next
+1.1a 10
diff --git a/usr.bin/learn/lib/C/L1.1a b/usr.bin/learn/lib/C/L1.1a
new file mode 100644
index 00000000000..a84b86b9b45
--- /dev/null
+++ b/usr.bin/learn/lib/C/L1.1a
@@ -0,0 +1,23 @@
+#print
+(Section 1.1)
+The way you compile a C program is to say
+ cc name.c
+where name.c is the name of the file the program
+is on. Here is a short C program that prints
+out a line containing "hello". Type it in and
+compile it. Call it anything you want but
+don't rename the output.
+When done, type "ready".
+
+main()
+{
+ printf("hello\n");
+}
+#once #create Ref
+hello
+#user
+a.out >x
+#cmp x Ref
+#log
+#next
+1.1b 10
diff --git a/usr.bin/learn/lib/C/L1.1b b/usr.bin/learn/lib/C/L1.1b
new file mode 100644
index 00000000000..93798736abb
--- /dev/null
+++ b/usr.bin/learn/lib/C/L1.1b
@@ -0,0 +1,31 @@
+#print
+(Section 1.1)
+Now write a C program that prints two lines,
+the first of which says "hello" and the second
+"goodbye". Don't forget those \n delimiters.
+Compile and test it. When satisfied,
+type "ready".
+#once #create Ref
+hello
+goodbye
+#user
+a.out >test
+#cmp test Ref
+#succeed
+Here is one possible solution to compare against yours.
+
+main()
+{
+ printf("hello\n");
+ printf("goodbye\n");
+}
+
+You could also combine the two messages into one
+call to printf, like
+
+ printf("hello\ngoodbye\n");
+
+but this is harder to read at a glance.
+#log
+#next
+1.1c 10
diff --git a/usr.bin/learn/lib/C/L1.1c b/usr.bin/learn/lib/C/L1.1c
new file mode 100644
index 00000000000..0ec06a30f59
--- /dev/null
+++ b/usr.bin/learn/lib/C/L1.1c
@@ -0,0 +1,18 @@
+#print
+(Section 1.1)
+The program in Ref.c has an error in it.
+Find it, fix it, and run it.
+Then type ready.
+#once #create Ref.c
+main()
+{
+ printf("hello\");
+}
+#once #create Ref
+hello
+#user
+a.out >x
+#cmp x Ref
+#log
+#next
+1.1d 10
diff --git a/usr.bin/learn/lib/C/L1.1d b/usr.bin/learn/lib/C/L1.1d
new file mode 100644
index 00000000000..1ee669389d0
--- /dev/null
+++ b/usr.bin/learn/lib/C/L1.1d
@@ -0,0 +1,33 @@
+#print
+(Section 1.1)
+Write a program which prints these four lines,
+exactly as shown:
+A tab is \t
+A backspace is \b
+A quote is \"
+A backslash is \\
+
+Compile it, test it, then type ready.
+#once #create Ref
+A tab is \t
+A backspace is \b
+A quote is \"
+A backslash is \\
+#user
+a.out >x
+#cmp x Ref
+#succeed
+One solution:
+
+main()
+{
+ printf("A tab is \\t\n");
+ printf("A backspace is \\b\n");
+ printf("A quote is \\\"\n");
+ printf("A backslash is \\\\\n");
+}
+#fail
+Watch out for those backslashes.
+#log
+#next
+1.1e 10
diff --git a/usr.bin/learn/lib/C/L1.1e b/usr.bin/learn/lib/C/L1.1e
new file mode 100644
index 00000000000..4a067909acb
--- /dev/null
+++ b/usr.bin/learn/lib/C/L1.1e
@@ -0,0 +1,14 @@
+#print
+What will be printed by the following printf statement?
+
+ printf("\"#@\"");
+
+Type "answer XXX", where XXX is the set of characters
+that will be printed.
+#copyin
+#user
+#uncopyin
+#match "#@"
+#log
+#next
+1.1f 10
diff --git a/usr.bin/learn/lib/C/L1.1f b/usr.bin/learn/lib/C/L1.1f
new file mode 100644
index 00000000000..b73e575d29b
--- /dev/null
+++ b/usr.bin/learn/lib/C/L1.1f
@@ -0,0 +1,19 @@
+#print
+(Section 1.2)
+Write a program to print
+the value of the character 'X' in
+octal. Compile it and run it.
+Then type ready.
+#user
+a.out >test
+grep 130 test >/dev/null
+#succeed
+A possible solution:
+
+main()
+{
+ printf("%o\n", 'X');
+}
+#log
+#next
+2.1a 10
diff --git a/usr.bin/learn/lib/C/L10 b/usr.bin/learn/lib/C/L10
new file mode 100644
index 00000000000..7599c4bbccd
--- /dev/null
+++ b/usr.bin/learn/lib/C/L10
@@ -0,0 +1,15 @@
+#print
+The lessons from this point on are from the old C script.
+They have not been cleaned up as much as they could, so some
+are not very illuminating, and the code they illustrate
+is not always the best. You're welcome to try them nonetheless,
+but be warned.
+If you want to proceed, type yes;
+otherwise, type bye.
+#copyin
+#user
+#uncopyin
+#match yes
+#next
+11.1a 10
+11.2a 5
diff --git a/usr.bin/learn/lib/C/L11.1a b/usr.bin/learn/lib/C/L11.1a
new file mode 100644
index 00000000000..4473506f65c
--- /dev/null
+++ b/usr.bin/learn/lib/C/L11.1a
@@ -0,0 +1,35 @@
+#print
+With your 'cc' command you can give the name of
+an object file to be loaded with your program.
+For example
+ cc x.c y.o
+will load the previously compiled program 'y' along with
+the program 'x' to be compiled now.
+
+The file "getnum.o" contains a subroutine "getnum" which
+reads an integer and returns its value.
+Write a program which reads a number and decides
+whether or not it is a multiple of 23. If so print
+"yes" and otherwise print "no".
+Compile and test; then type "ready".
+#once #create Ref1
+23000
+#once #create Ref2
+23001
+#once cp %s/getnum.o .
+#user
+a.out <Ref1 >z1
+a.out <Ref2 >z2
+grep yes z1 >/dev/null && grep no z2 >/dev/null
+#succeed
+/* One way: */
+
+main() {
+ if (getnum()%23 == 0)
+ printf("yes\n");
+ else
+ printf("no\n");
+}
+#log
+#next
+12.1a 10
diff --git a/usr.bin/learn/lib/C/L11.2a b/usr.bin/learn/lib/C/L11.2a
new file mode 100644
index 00000000000..154493d6890
--- /dev/null
+++ b/usr.bin/learn/lib/C/L11.2a
@@ -0,0 +1,29 @@
+#print
+With your 'cc' command you can give the name of
+an object file to be loaded with your program.
+For example
+ cc x.c y.o
+will load the previously compiled program 'y' along with
+the program 'x' to be compiled now.
+There is a file in this directory named "getnum.o"
+that contains a subroutine "getnum" that will read digits
+from the standard input, convert them to binary, and
+return an integer value.
+
+Write a program which reads an integer and prints
+it back in octal. Compile and test as usual.
+#once #create Ref
+254
+#once cp %s/getnum.o .
+#user
+a.out <Ref >test
+grep 376 test >/dev/null
+#succeed
+/* One way: */
+
+main() {
+ printf("%o\n", getnum());
+}
+#log
+#next
+11.1a 10
diff --git a/usr.bin/learn/lib/C/L12.1a b/usr.bin/learn/lib/C/L12.1a
new file mode 100644
index 00000000000..ad51d56c842
--- /dev/null
+++ b/usr.bin/learn/lib/C/L12.1a
@@ -0,0 +1,35 @@
+#print
+Write a program which reads two numbers and
+prints the larger one in decimal. Use the same
+"getnum" subroutine. Compile, test and type
+"ready" as usual.
+#once #create Ref1
+14039 89
+#once #create Ref2
+20022 23001
+#once cp %s/getnum.o .
+#user
+a.out <Ref1 >x1
+a.out <Ref2 >x2
+grep 14039 x1 >/dev/null && grep 23001 x2 >/dev/null
+#succeed
+/* One way: */
+
+main() {
+ int n1, n2;
+
+ n1 = getnum();
+ n2 = getnum();
+ printf("%d\n", n1 > n2 ? n1 : n2);
+}
+
+/* You could also use something like
+
+ if (n1 > n2)
+ printf("%d\n", n1);
+ else
+ printf("%d\n", n2);
+ */
+#log
+#next
+12.1b 10
diff --git a/usr.bin/learn/lib/C/L12.1b b/usr.bin/learn/lib/C/L12.1b
new file mode 100644
index 00000000000..3f60b51bdec
--- /dev/null
+++ b/usr.bin/learn/lib/C/L12.1b
@@ -0,0 +1,60 @@
+#print
+The function getnum actually returns -1 when it
+encounters end of file. (The source is in getnum.c
+if you're interested.)
+Write, compile and run a program that
+reads numbers one per line with getnum
+and, for each, prints:
+
+small if the number is >0 and <=100
+big if the number is >100 and <=1000
+huge if the number is >1000.
+
+Type "ready" when you're done.
+#once cp %s/getnum.o .
+#once cp %s/getnum.c .
+#once #create Ref
+1001
+1000
+999
+101
+100
+1
+#once #create Ref1
+huge
+big
+big
+big
+small
+small
+#user
+a.out <Ref >test
+#cmp Ref1 test
+#succeed
+/* One way:*/
+
+main() {
+ int n;
+
+ while ((n = getnum()) >= 0)
+ if (n > 0 && n <= 100)
+ printf("small\n");
+ else if (n > 100 && n <= 1000)
+ printf("big\n");
+ else if (n > 1000)
+ printf("huge\n");
+}
+
+/* Notice that in principle n could be negative,
+ so we need the last case to say
+ else if (n > 1000)
+ instead of just falling into it with a bare
+ else
+
+ Also it's a good idea to indent the else-if's
+ exactly the way they are here; otherwise
+ you'll lose track of what's going on.
+**/
+#log
+#next
+13.1a 10
diff --git a/usr.bin/learn/lib/C/L13.1a b/usr.bin/learn/lib/C/L13.1a
new file mode 100644
index 00000000000..a70bd13fda7
--- /dev/null
+++ b/usr.bin/learn/lib/C/L13.1a
@@ -0,0 +1,39 @@
+#print
+Write a program which reads
+its input and counts the number of
+characters and the number of spaces
+(where a space is either a blank or
+a tab or a newline). Print both numbers.
+Compile, test, and type "ready".
+#once #create Ref
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+gillette stirling millington lyons basking ridge
+bernardsville far hills peapack gladstone
+#user
+a.out <Ref >x1
+a.out <Ref >x2
+grep 348 x1 >/dev/null && grep 45 x2 >/dev/null
+#succeed
+ #include <stdio.h>
+/* One way: */
+
+main() {
+ int nchar, nspace;
+ char c;
+
+ nchar = nspace = 0;
+ while ((c = getchar()) != EOF) {
+ nchar++;
+ if (c == ' ' || c == '\t' || c == '\n')
+ nspace++;
+ }
+ printf("spaces = %d, chars = %d\n", nspace, nchar);
+}
+#log
+#next
+14.1a 10
+14.2a 5
diff --git a/usr.bin/learn/lib/C/L14.1a b/usr.bin/learn/lib/C/L14.1a
new file mode 100644
index 00000000000..fd3de193d16
--- /dev/null
+++ b/usr.bin/learn/lib/C/L14.1a
@@ -0,0 +1,38 @@
+#print
+Using the familar "getnum.o" routine
+write a program that reads numbers one per line and determines
+for each if it is prime. Print "prime"
+for a prime number and "composite" for a non-prime number.
+Compile, test, and type "ready".
+#once #create Ref
+10039
+17947
+#once #create Ref1
+prime
+composite
+#once cp %s/getnum.o .
+#user
+a.out <Ref >x1
+#cmp x1 Ref1
+#succeed
+/* A slow but sure prime-tester */
+main()
+{
+ int p, i, comp;
+
+ while ((p = getnum()) >= 0) {
+ comp = 0;
+ for (i = 2; i*i <= p; i++)
+ if (p%i == 0) {
+ comp = 1;
+ break;
+ }
+ if (comp)
+ printf("composite\n");
+ else
+ printf("prime\n");
+ }
+}
+#log
+#next
+15.1a 10
diff --git a/usr.bin/learn/lib/C/L14.2a b/usr.bin/learn/lib/C/L14.2a
new file mode 100644
index 00000000000..01cc54f6129
--- /dev/null
+++ b/usr.bin/learn/lib/C/L14.2a
@@ -0,0 +1,26 @@
+#print
+Using the "getnum" routine on "getnum.o", write a program
+that reads a list of positive numbers and prints their sum. Stop reading
+numbers when "getnum" returns a negative or zero value.
+Compile and test your program; then type "ready".
+#once #create Ref
+5 43 293 400 75 832 903 33
+#once cp %s/getnum.o .
+#user
+a.out <Ref >xxx
+grep 2584 xxx >/dev/null
+#succeed
+/* Read numbers and count */
+main()
+{
+ int s, n;
+
+ s = 0;
+ while ((n=getnum()) > 0)
+ s += n;
+ printf("Sum is %d\n", s);
+}
+#log
+#next
+14.2b 5
+15.1a 10
diff --git a/usr.bin/learn/lib/C/L14.2b b/usr.bin/learn/lib/C/L14.2b
new file mode 100644
index 00000000000..66633049b67
--- /dev/null
+++ b/usr.bin/learn/lib/C/L14.2b
@@ -0,0 +1,41 @@
+#print
+Write a program which counts the number of five letter
+words in its input (define a word as anything between
+blanks, tabs or newlines). Compile and run it, then type "ready".
+Note that all that is wanted is the total number of
+five letter words - nothing was said about distinct
+words. Just count the number of times exactly five
+characters appear between spaces.
+#once #create Ref
+This is a passage of text which contains
+exactly twelve words of five letters.
+Words may appear at the start or at the final
+part of a line. Other words show up in
+the middle. Avoid counting seven or eight letters
+but every five must be noted.
+#user
+a.out <Ref >xxx
+grep 12 xxx >/dev/null
+#succeed
+/* one way to count five letter words */
+ #include <stdio.h>
+
+main()
+{
+ int since, wdnum, c;
+
+ since = 0;
+ while ((c=getchar()) != EOF) {
+ if (c == ' ' || c == '\t' || c == '\n') {
+ if (since == 5)
+ wdnum++;
+ since = 0;
+ }
+ else
+ since++;
+ }
+ printf("%d\n", wdnum);
+}
+#log
+#next
+15.1a 10
diff --git a/usr.bin/learn/lib/C/L15.1a b/usr.bin/learn/lib/C/L15.1a
new file mode 100644
index 00000000000..e1b7a6ec62f
--- /dev/null
+++ b/usr.bin/learn/lib/C/L15.1a
@@ -0,0 +1,33 @@
+#print
+Write a program that reads in lines one at a time,
+and prints them out if their length (including
+the newline) is odd.
+You can use the function getline if you like; the object
+file is in getline.o.
+Compile and run it, then type "ready".
+#once #create Ref1
+this line contains an odd number of letters!
+this line, however, contains an even number of letters!
+#once #create Ref2
+this line contains an odd number of letters!
+#once cp %s/getline.o .
+#user
+a.out <Ref1 >x1
+#cmp x1 Ref2
+#succeed
+/* It's certainly easiest with getline: */
+
+ #include <stdio.h>
+
+main()
+{
+ char line[500];
+ int n;
+
+ while ((n = getline(line, 500)) > 0)
+ if (n % 2 == 1)
+ printf("%s", line);
+}
+#log
+#next
+15.1b 10
diff --git a/usr.bin/learn/lib/C/L15.1b b/usr.bin/learn/lib/C/L15.1b
new file mode 100644
index 00000000000..d0032a8397a
--- /dev/null
+++ b/usr.bin/learn/lib/C/L15.1b
@@ -0,0 +1,40 @@
+#print
+Write a program that reads in lines, and prints each out
+in reverse order (except that the newline should be
+at the end).
+Thus the line
+cat food
+should come out as
+doof tac
+Compile it and run it, then type "ready".
+#once #create Ref1
+This is odd.
+This is even.
+
+#once #create Ref2
+.ddo si sihT
+.neve si sihT
+
+#once cp %s/getline.o .
+#user
+a.out <Ref1 >x1
+#cmp x1 Ref2
+#succeed
+/* one way to do this */
+ #include <stdio.h>
+
+main()
+{
+ char line[500];
+ int n;
+
+ while ((n = getline(line, 500)) > 0) {
+ for (n -= 2; n >= 0; n--)
+ putchar(line[n]);
+ putchar('\n');
+ }
+}
+#log
+#next
+17.1a 10
+16.2a 5
diff --git a/usr.bin/learn/lib/C/L16.2a b/usr.bin/learn/lib/C/L16.2a
new file mode 100644
index 00000000000..7c753d95652
--- /dev/null
+++ b/usr.bin/learn/lib/C/L16.2a
@@ -0,0 +1,54 @@
+#print
+Write a program which reads a file with lines of up
+to 200 characters and shortens them to 60 characters
+by throwing away any characters past the first 60.
+Compile and test it; then type "ready".
+#once #create Ref
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue east orange
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown summit cha
+new providence murray hill berkeley heights
+
+gillette stirling millingon lyons basking ridgexxxxxxxxxxxxx
+bernardsville far hills peapack gladstone
+#once #create badin
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue east orange brick church orange highland avenue east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown summit chatham madison convent station morristown summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+
+gillette stirling millingon lyons basking ridgexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+bernardsville far hills peapack gladstone
+#user
+a.out <badin >xxx
+#cmp Ref xxx
+#succeed
+/* one way to do this */
+ #include <stdio.h>
+
+main()
+{
+ char line[61];
+ int c, k;
+
+ k = 0;
+ while ((c = getchar()) != EOF) {
+ if (c == '\n') {
+ line[k] = 0;
+ printf("%s\n", line);
+ k = 0;
+ }
+ else if (k < 60)
+ line[k++] = c;
+ }
+}
+
+/* Note that this version works regardless of
+how long the lines are. If you use getline,
+is the same thing true??
+ */
+#log
+#next
+16.2b 10
diff --git a/usr.bin/learn/lib/C/L16.2b b/usr.bin/learn/lib/C/L16.2b
new file mode 100644
index 00000000000..3d4bf96dfab
--- /dev/null
+++ b/usr.bin/learn/lib/C/L16.2b
@@ -0,0 +1,40 @@
+#print
+Write a program which copies all lines containng
+the letter 'p' from its input to its output.
+Compile and test it; then type "ready".
+#once #create Ref
+mountain station south orange maplewood millburn short hills
+new providence murray hill berkeley heights
+bernardsville far hills peapack gladstone
+#once #create badin
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+gillette stirling millington lyons basking ridge
+bernardsville far hills peapack gladstone
+#once cp %s/getline.o .
+#user
+a.out <badin >xxx
+#cmp Ref xxx
+#succeed
+/* a way to find lines with 'p' */
+ #include <stdio.h>
+
+main()
+{
+ char line[500];
+ int k;
+
+ while (getline(line, 500) > 0)
+ for (k = 0; line[k] != '\0'; k++)
+ if (line[k] == 'p') {
+ printf("%s", line);
+ break;
+ }
+}
+#log
+#next
+16.2c 5
+17.1a 10
diff --git a/usr.bin/learn/lib/C/L16.2c b/usr.bin/learn/lib/C/L16.2c
new file mode 100644
index 00000000000..b170a71e838
--- /dev/null
+++ b/usr.bin/learn/lib/C/L16.2c
@@ -0,0 +1,67 @@
+#print
+Write a program to read its input and find the
+word in it with the most vowels (instances of a,e,i,o, or u).
+Print out that word. Compile and test your
+program, then type ready.
+#once #create Ref
+When in the course of human events, it becomes
+necessary for one people to dissolve the political bands which have
+connected them with another, and to assume among the
+powers of the earth the separate and equal station to which
+the laws of Nature and of Nature's God entitle them, a decent
+respect to the opinions of mankind requires that they should
+declare the causes which impel them to the separation.
+ We hold these truths to be self evident, that all men
+are created equal, that they are endowed by their creator
+with certain unalienable rights, that among these are life, liberty,
+and the pursuit of happiness. That to secure these rights,
+governments are instituted among men, deriving their just
+powers from the consent of the governed. That whenever
+any form of government becomes destructive of these ends,
+it is the right of the people to alter or to abolish it, and
+to institute new government, laying its foundation on such
+principles and organizing its powers in such form, as to them
+shall seem most likely to effect their safety and happiness.
+#user
+a.out <Ref >xxx
+grep unalienable xxx >/dev/null
+#succeed
+/* a way to find a word with lots of vowels */
+ #include <stdio.h>
+
+main()
+{
+ char bigword[100], thisword[100];
+ int nvow, maxvow, c, k;
+
+ maxvow = k = 0;
+ while ((c = getchar()) != EOF) {
+ if (c == '\n' || c == ' ') {
+ if (nvow > maxvow) {
+ copy(thisword, bigword, k);
+ maxvow = nvow;
+ }
+ nvow = k = 0;
+ } else {
+ thisword[k++] = c;
+ switch (c) {
+ case 'a': case 'e': case 'i': case 'o': case 'u':
+ nvow++;
+ }
+ }
+ }
+ printf("the word %s had %d vowels\n", bigword, maxvow);
+}
+
+copy(a, b, n)
+char a[], b[];
+{
+ int i;
+
+ for(i = 0; i < n; i++)
+ b[i] = a[i];
+ b[i] = 0;
+}
+#log
+#next
+17.1a 10
diff --git a/usr.bin/learn/lib/C/L17.1a b/usr.bin/learn/lib/C/L17.1a
new file mode 100644
index 00000000000..7c3976cc705
--- /dev/null
+++ b/usr.bin/learn/lib/C/L17.1a
@@ -0,0 +1,71 @@
+#print
+Write in a program which reads its input and writes it
+out line numbered, with a three-digit line number (starting at one)
+followed by a single space and then by the original line.
+Note: the printf format specification %3d will print a three
+digit number.
+You might try the function fgets (part of the standard library).
+ fgets(buf, size, stdin)
+reads from the terminal ("stdin") up to size characters
+into buf. It returns NULL on end of file.
+
+Compile and test your program; then type "ready".
+#once #create Ref
+When in the course of human events, it becomes
+necessary for one people to dissolve the political bands which have
+connected them with another, and to assume among the
+powers of the earth the separate and equal station to which
+the laws of Nature and of Nature's God entitle them, a decent
+respect to the opinions of mankind requires that they should
+declare the causes which impel them to the separation.
+ We hold these truths to be self evident, that all men
+are created equal, that they are endowed by their creator
+with certain unalienable rights, that among these are life, liberty,
+and the pursuit of happiness. That to secure these rights,
+governments are instituted among men, deriving their just
+powers from the consent of the governed. That whenever
+any form of government becomes destructive of these ends,
+it is the right of the people to alter or to abolish it, and
+to institute new government, laying its foundation on such
+principles and organizing its powers in such form, as to them
+shall seem most likely to effect their safety and happiness.
+#once #create reffed
+ 1 When in the course of human events, it becomes
+ 2 necessary for one people to dissolve the political bands which have
+ 3 connected them with another, and to assume among the
+ 4 powers of the earth the separate and equal station to which
+ 5 the laws of Nature and of Nature's God entitle them, a decent
+ 6 respect to the opinions of mankind requires that they should
+ 7 declare the causes which impel them to the separation.
+ 8 We hold these truths to be self evident, that all men
+ 9 are created equal, that they are endowed by their creator
+ 10 with certain unalienable rights, that among these are life, liberty,
+ 11 and the pursuit of happiness. That to secure these rights,
+ 12 governments are instituted among men, deriving their just
+ 13 powers from the consent of the governed. That whenever
+ 14 any form of government becomes destructive of these ends,
+ 15 it is the right of the people to alter or to abolish it, and
+ 16 to institute new government, laying its foundation on such
+ 17 principles and organizing its powers in such form, as to them
+ 18 shall seem most likely to effect their safety and happiness.
+#user
+a.out <Ref >xxx
+#cmp xxx reffed
+#succeed
+
+
+ #include <stdio.h>
+
+main()
+{
+ char s[200];
+ int k;
+
+ k = 0;
+ while (fgets(s, 200, stdin) != NULL)
+ printf("%3d %s", ++k, s);
+}
+#log
+#next
+18.1a 10
+17.1c 5
diff --git a/usr.bin/learn/lib/C/L17.1c b/usr.bin/learn/lib/C/L17.1c
new file mode 100644
index 00000000000..c7eb76ce64b
--- /dev/null
+++ b/usr.bin/learn/lib/C/L17.1c
@@ -0,0 +1,50 @@
+#print
+Print the 20 Fibonacci numbers beginning with 2
+(the sequence is 2,3,5,8,... where each number
+is the sum of the immediately preceding pair of numbers.
+Start with the pair 1,1).
+Print each number on a separate line as a five digit
+number (remember %3d in printf? %5d does five digits).
+Compile and test your program; then type "ready".
+#once #create Ref
+ 2
+ 3
+ 5
+ 8
+ 13
+ 21
+ 34
+ 55
+ 89
+ 144
+ 233
+ 377
+ 610
+ 987
+ 1597
+ 2584
+ 4181
+ 6765
+10946
+17711
+#user
+a.out >xxx
+#cmp xxx Ref
+#succeed
+/* one way */
+main()
+{
+ int f1, f2, t, count;
+
+ f1 = 1;
+ f2 = 1;
+ for (count = 0; count < 20; count++) {
+ t = f1+f2;
+ f1 = f2;
+ f2 = t;
+ printf("%5d\n", t);
+ }
+}
+#log
+#next
+18.1a 10
diff --git a/usr.bin/learn/lib/C/L18.1a b/usr.bin/learn/lib/C/L18.1a
new file mode 100644
index 00000000000..89a9150f060
--- /dev/null
+++ b/usr.bin/learn/lib/C/L18.1a
@@ -0,0 +1,49 @@
+#print
+There is nothing to force you to write a main program
+on each file; just as I supplied "getnum" on a separate file,
+you can put different routines on different files. Write
+a function "length(s)" which if given a character array argument
+"s" returns the length of that string.
+Put this on a file named "length.c", and leave
+the object file in "length.o".
+Write the main program for
+testing this somewhere else. Type "ready" when you have compiled
+and tested your program and are happy with it.
+#once #create Ref
+This file contains several lines of quite different lengths.
+
+You should get
+all of them exactly
+r
+right.
+#once #create answer
+60
+0
+14
+19
+1
+6
+#once #create tzaqc.c
+main() {
+ char s[200];
+ while (gets(s))
+ printf("%d\n", length(s));
+}
+#user
+cc tzaqc.c length.c
+a.out <Ref >value
+#cmp value answer
+#succeed
+/* one way */
+length(s)
+char *s;
+{
+ int k;
+
+ for (k=0; s[k]; k++)
+ ;
+ return(k);
+}
+#log
+#next
+19.1a 10
diff --git a/usr.bin/learn/lib/C/L19.1a b/usr.bin/learn/lib/C/L19.1a
new file mode 100644
index 00000000000..21e46af064b
--- /dev/null
+++ b/usr.bin/learn/lib/C/L19.1a
@@ -0,0 +1,29 @@
+#print
+Write a subroutine which counts the number of times it has
+been called and returns that count each time. Name it
+"count()". Write it on a file named "count.c". Compile
+and test it; type "ready" when happy.
+#once #create Ref
+23080
+#once #create tzaqc.c
+main() {
+ int i;
+ for (i = 0; i < 23079; i++)
+ count();
+ printf("%d\n", count());
+}
+#user
+cc tzaqc.c count.o
+a.out >value
+#cmp value Ref
+#succeed
+/* one way */
+count()
+{
+ static int n = 0;
+ return(++n);
+}
+#log
+#next
+30.1a 10
+20.1a 5
diff --git a/usr.bin/learn/lib/C/L2.1a b/usr.bin/learn/lib/C/L2.1a
new file mode 100644
index 00000000000..43e3bafa150
--- /dev/null
+++ b/usr.bin/learn/lib/C/L2.1a
@@ -0,0 +1,55 @@
+#print
+(Section 1.2)
+The file Ref.c contains a copy of
+a program to convert Fahrenheit to
+Celsius. Modify it to print this
+heading at the top:
+Fahrenheit-Celsius Conversion
+ F: C:
+Type ready when you're satisfied.
+#once #create Ref
+Fahrenheit-Celsius Conversion
+ F: C:
+ 0 -17.8
+ 20 -6.7
+ 40 4.4
+ 60 15.6
+ 80 26.7
+ 100 37.8
+ 120 48.9
+ 140 60.0
+ 160 71.1
+ 180 82.2
+ 200 93.3
+ 220 104.4
+ 240 115.6
+ 260 126.7
+ 280 137.8
+ 300 148.9
+#once #create Ref.c
+/* print Fahrenheit-Celsius table
+ for f = 0, 20, ..., 300 */
+main()
+{
+ int lower, upper, step;
+ float fahr, celsius;
+
+ lower = 0; /* lower limit of temperature table */
+ upper = 300; /* upper limit */
+ step = 20; /* step size */
+
+ fahr = lower;
+ while (fahr <= upper) {
+ celsius = (5.0/9.0) * (fahr-32.0);
+ printf("%4.0f %6.1f\n", fahr, celsius);
+ fahr = fahr + step;
+ }
+}
+#user
+a.out >x
+#cmp Ref x
+#fail
+Make sure you get the spacing right.
+#log
+#next
+2.1b 10
diff --git a/usr.bin/learn/lib/C/L2.1b b/usr.bin/learn/lib/C/L2.1b
new file mode 100644
index 00000000000..efc9a0e7157
--- /dev/null
+++ b/usr.bin/learn/lib/C/L2.1b
@@ -0,0 +1,21 @@
+#print
+(Section 1.2)
+Write a C program that prints a number which is
+the sum of three numbers: 23, 197, and the product
+of 23 and 197. Again, compile and test
+it. Please do the computation with the program -
+if you do it by hand, I'll give you credit for the
+work, but it's just stupid.
+#user
+a.out >test
+grep 4751 test >/dev/null
+#succeed
+/* Here is one possible solution */
+
+main()
+{
+ printf("%d\n", 23 + 197 + 23*197);
+}
+#log
+#next
+2.1c 10
diff --git a/usr.bin/learn/lib/C/L2.1c b/usr.bin/learn/lib/C/L2.1c
new file mode 100644
index 00000000000..4158208bb59
--- /dev/null
+++ b/usr.bin/learn/lib/C/L2.1c
@@ -0,0 +1,16 @@
+#print
+(Section 1.2)
+What value is printed by this printf statement?
+
+ printf("%.3f", 3.141592654);
+
+Type "answer XXX", where XXX is the value.
+#copyin
+#user
+#uncopyin
+#match 3.142
+#fail
+Remember about rounding?
+#log
+#next
+2.1d 10
diff --git a/usr.bin/learn/lib/C/L2.1d b/usr.bin/learn/lib/C/L2.1d
new file mode 100644
index 00000000000..94f328efd30
--- /dev/null
+++ b/usr.bin/learn/lib/C/L2.1d
@@ -0,0 +1,15 @@
+#print
+What value is printed by this printf statement?
+
+ printf("%%3.1f", 3.141592654);
+
+Type "answer XXX", where XXX is the value.
+#copyin
+#user
+#uncopyin
+#match %3.1f
+#fail
+Look again - it's %%
+#log
+#next
+2.1e 10
diff --git a/usr.bin/learn/lib/C/L2.1e b/usr.bin/learn/lib/C/L2.1e
new file mode 100644
index 00000000000..86df6328efd
--- /dev/null
+++ b/usr.bin/learn/lib/C/L2.1e
@@ -0,0 +1,19 @@
+#print
+Is there any difference between
+
+ printf("%s", s);
+
+and
+
+ printf(s);
+
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#fail
+Consider the string "50% of the answers are wrong."
+#log
+#next
+3.1a 10
diff --git a/usr.bin/learn/lib/C/L20.1a b/usr.bin/learn/lib/C/L20.1a
new file mode 100644
index 00000000000..0d2d5d11a95
--- /dev/null
+++ b/usr.bin/learn/lib/C/L20.1a
@@ -0,0 +1,105 @@
+#print
+Write a program to read a list of positive numbers
+and sort them into ascending order. Print
+the sorted list of numbers one per line
+as five digit numbers (%5d in printf).
+Stop reading numbers when getnum returns -1.
+Compile and test your program; then type "ready".
+#once #create Ref
+ 1
+ 3
+ 4
+ 9
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 20
+ 34
+ 71
+ 200
+ 225
+ 250
+ 275
+ 300
+ 4095
+ 7111
+16384
+#once cp %s/getnum.o .
+#once #create input
+4 20 3 200 16384 4095 71 11 12 13 14
+15 16 17 34 9 7111 300 275 250 225 1
+#user
+a.out <input >xxx
+#cmp xxx Ref
+#succeed
+main()
+{
+ int n;
+ int list[1000];
+
+ n = getlist(list);
+ shellsort(list, n);
+ printlist(list, n);
+}
+
+getlist(list)
+int list[];
+{
+ int n;
+
+ n = 0;
+ while ((list[n]=getnum()) >= 0)
+ n++;
+ return(n);
+}
+
+/* this is a shell sort, stripped down to process a list
+ of integers only. Although you probably don't know
+ how to write this offhand, you should know where to find
+ it - it is only marginally more code than a bubble sort
+ and much faster (n**1.5 vs. n**2) in time. */
+shellsort(v, n) /* sort v[0]...v[n-1] into increasing order */
+int v[], n;
+{
+ int gap, i, j, temp;
+
+ for (gap = n/2; gap > 0; gap /= 2)
+ for (i = gap; i < n; i++)
+ for (j=i-gap; j>=0 && v[j]>v[j+gap]; j-=gap) {
+ temp = v[j];
+ v[j] = v[j+gap];
+ v[j+gap] = temp;
+ }
+}
+
+printlist(list, n)
+int list[], n;
+{
+ int i;
+ for(i=0; i<n; i++)
+ printf("%5d\n",list[i]);
+}
+/* this is a crummy bubble sort which
+ would work perfectly well for this
+ problem but can not be recommended
+ for large jobs.
+sortlist()
+{
+ int i, j, k;
+
+ for(i=0; i<n; i++)
+ for(j=n-1; j>0; j--)
+ if (list[j-1] > list[j]) {
+ k = list[j];
+ list[j] = list[j-1];
+ list[j-1] = k;
+ }
+}
+ ****/
+#log
+#next
+30.1a 10
diff --git a/usr.bin/learn/lib/C/L3.1a b/usr.bin/learn/lib/C/L3.1a
new file mode 100644
index 00000000000..9efe184ac7c
--- /dev/null
+++ b/usr.bin/learn/lib/C/L3.1a
@@ -0,0 +1,56 @@
+#print
+(Section 1.3)
+The file Ref.c contains a copy of
+a program to convert Fahrenheit to
+Celsius that prints from 0 to 300
+degrees in steps of 20.
+Modify it to print from 300 down to 0
+in steps of 50. Type ready when you're done.
+#once #create Ref
+ 300 148.9
+ 250 121.1
+ 200 93.3
+ 150 65.6
+ 100 37.8
+ 50 10.0
+ 0 -17.8
+#once #create Ref.c
+/* print Fahrenheit-Celsius table
+ for f = 0, 20, ..., 300 */
+main()
+{
+ int lower, upper, step;
+ float fahr, celsius;
+
+ lower = 0; /* lower limit of temperature table */
+ upper = 300; /* upper limit */
+ step = 20; /* step size */
+
+ fahr = lower;
+ while (fahr <= upper) {
+ celsius = (5.0/9.0) * (fahr-32.0);
+ printf("%4.0f %6.1f\n", fahr, celsius);
+ fahr = fahr + step;
+ }
+}
+#user
+a.out >x
+#cmp Ref x
+#succeed
+Here's our solution:
+
+main() /* Fahrenheit-Celsius 300 ... 0 by 50 */
+{
+ int lower, upper, step;
+ float fahr;
+
+ lower = 0; /* lower limit of temperature table */
+ upper = 300; /* upper limit */
+ step = 50; /* step size */
+
+ for (fahr = upper; fahr >= lower; fahr = fahr - step)
+ printf("%4.0f %6.1f\n", fahr, (5.0/9.0) * (fahr-32.0));
+}
+#log
+#next
+3.1b 10
diff --git a/usr.bin/learn/lib/C/L3.1b b/usr.bin/learn/lib/C/L3.1b
new file mode 100644
index 00000000000..33823309455
--- /dev/null
+++ b/usr.bin/learn/lib/C/L3.1b
@@ -0,0 +1,14 @@
+#print
+What is the value of i after this
+___for statement executes?
+Type "answer N", where N is the value of i.
+
+ for (i = 0; i < 10; i = i + 3)
+ ;
+#copyin
+#user
+#uncopyin
+#match 12
+#log
+#next
+4.1a 10
diff --git a/usr.bin/learn/lib/C/L30.1a b/usr.bin/learn/lib/C/L30.1a
new file mode 100644
index 00000000000..6a70af3612f
--- /dev/null
+++ b/usr.bin/learn/lib/C/L30.1a
@@ -0,0 +1,45 @@
+#print
+Write a subroutine named "locn(s,c)" which expects two
+arguments: the first is a pointer to characters 's' which
+points to a null-terminated string, and the second
+is a character 'c' which is to be searched for in the
+string 's'. If the character 'c' does not
+appear in the string return 0; otherwise return a pointer
+to the position of 'c' in the string. Name the program "locn.c";
+as usual, compile and test it and then type "ready".
+#once #create Ref
+0
+19
+0
+25
+0
+#once #create tzaqc.c
+char *alpha "abcdefghijklmnopqrstuvwxyz";
+main()
+{
+ extern char *locn();
+ printf("%d\n", locn(alpha, '+'));
+ printf("%d\n",locn(alpha, 't')-alpha);
+ printf("%d\n",locn(alpha, 'a')-alpha);
+ printf("%d\n",locn(alpha, 'z')-alpha);
+ printf("%d\n",locn("", 'z'));
+}
+#user
+cc tzaqc.c locn.o
+a.out >value
+#cmp value Ref
+#succeed
+/* Try this: */
+
+char *
+locn (s, c)
+char *s;
+{
+ for( ; *s; s++)
+ if (*s == c)
+ return(s);
+ return(0);
+}
+#log
+#next
+31.1a 10
diff --git a/usr.bin/learn/lib/C/L31.1a b/usr.bin/learn/lib/C/L31.1a
new file mode 100644
index 00000000000..81d1bf9313b
--- /dev/null
+++ b/usr.bin/learn/lib/C/L31.1a
@@ -0,0 +1,48 @@
+#print
+Write a function named "rev(s)" which reverses
+the string "s" in place. Name the file that contains
+the function "rev.c".
+When you're satisfied, type "ready".
+#once #create Ref
+cbax0987654321
+#once #create tzaqc.c
+main(){
+ char *s1, *s2, *s3, *s4;
+ s1 = "abc";
+ s2 = "x";
+ s3 = "";
+ s4 = "1234567890";
+ rev(s1);
+ rev(s2);
+ rev(s3);
+ rev(s4);
+ printf(s1);
+ printf(s2);
+ printf(s3);
+ printf(s4);
+ printf("\n");
+}
+#user
+cc tzaqc.c rev.o
+a.out >value
+#cmp value Ref
+#succeed
+/* One way:*/
+
+rev (s)
+char *s;
+{
+ char *p;
+ int t;
+
+ for (p=s; *p; p++)
+ ;
+ for (p--; p > s; p--, s++) {
+ t = *p;
+ *p = *s;
+ *s = t;
+ }
+}
+#log
+#next
+32.1a 10
diff --git a/usr.bin/learn/lib/C/L32.1a b/usr.bin/learn/lib/C/L32.1a
new file mode 100644
index 00000000000..7352cd7e9f5
--- /dev/null
+++ b/usr.bin/learn/lib/C/L32.1a
@@ -0,0 +1,50 @@
+#print
+Write a program
+ pair(a,b)
+which accepts as arguments two pointers to integers
+and swaps the integers if necessary so that the
+first argument points to the larger one; that is
+ int x,y;
+ x = 9;
+ y = 15;
+ pair( &x, &y);
+results in x being 15 and y 9. Leave the program
+on file "pair.c"; compile, test it, and type "ready".
+#once #create tzaqc.c
+main()
+{
+ int x,y;
+
+ y=200;
+ x = 0;
+ pair(&y, &x);
+ if (x != 0 || y != 200)
+ return(1);
+ pair(&x,&y);
+ if (x != 200 || y != 0)
+ return(1);
+ x = 30;
+ y = 23097;
+ pair(&x,&y);
+ if (x != 23097 || y != 30)
+ return(1);
+ return(0);
+}
+#user
+cc tzaqc.c pair.o
+a.out
+#succeed
+pair(a, b)
+int *a, *b;
+{
+ int t;
+
+ if (*a <= *b) {
+ t = *a;
+ *a = *b;
+ *b = t;
+ }
+}
+#log
+#next
+33.1a 10
diff --git a/usr.bin/learn/lib/C/L33.1a b/usr.bin/learn/lib/C/L33.1a
new file mode 100644
index 00000000000..e421f55eb7c
--- /dev/null
+++ b/usr.bin/learn/lib/C/L33.1a
@@ -0,0 +1,23 @@
+#print
+Write a main program which counts the number of command-line arguments
+it has which begin with the letter 'b'. Print the
+result in decimal. Compile and test it as usual.
+Then type "ready".
+#user
+a.out abc bcd efg rpq b bbvd >xxx
+grep 3 xxx >/dev/null
+#succeed
+/* a possible solution */
+main(argc, argv)
+char *argv[];
+{
+ int i, k;
+
+ for(i=k=0; i<argc; i++)
+ if (argv[i][0] == 'b')
+ k++;
+ printf("%d\n", k);
+}
+#log
+#next
+37.1a 10
diff --git a/usr.bin/learn/lib/C/L35.1a b/usr.bin/learn/lib/C/L35.1a
new file mode 100644
index 00000000000..c6f7c0d87b4
--- /dev/null
+++ b/usr.bin/learn/lib/C/L35.1a
@@ -0,0 +1,35 @@
+#print
+Write a program which prints the number of vowels
+(instances of 'a', 'e', 'i', 'o', and 'u')
+in the input.
+#once #create Ref
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+gillette stirling millington lyons basking ridge
+bernardsville far hills peapack gladstone
+#user
+a.out <Ref >xxx
+grep 109 xxx >/dev/null
+#succeed
+/* a possible solution */
+ #include <stdio.h>
+
+main()
+{
+ int k, c;
+
+ k = 0;
+ while ((c = getchar()) != EOF)
+ switch (c) {
+ case 'a': case 'e':case 'i': case 'o': case 'u':
+ k++;
+ break;
+ }
+ printf("%d\n", k);
+}
+#log
+#next
+37.1a 10
diff --git a/usr.bin/learn/lib/C/L37.1a b/usr.bin/learn/lib/C/L37.1a
new file mode 100644
index 00000000000..55a3e4c5130
--- /dev/null
+++ b/usr.bin/learn/lib/C/L37.1a
@@ -0,0 +1,57 @@
+#print
+Let's try a recursive function. Write a subroutine
+ power(x,n)
+which computes x to the power n by the following
+algorithm:
+ 1. if n is zero return 1.
+ 2. if n is odd return x*power(x,n-1).
+ 3. if n is even return the square of
+ power(x,n/2).
+You may assume than x and n are integers, n>=0.
+If n is negative return 0 for an answer.
+Put your routine on a file "power.c". Compile
+it and test it; then type "ready".
+#once #create tzaqc.c
+main()
+{
+if (power(-1,-1) != 0)
+ return(1);
+ if (power(-3,2) != 9)
+ return(1);
+ if (power(2,12) != 4096)
+ return(1);
+ if (power(3,5) != 243)
+ return(1);
+ if (power(-5, 5) != -3125)
+ return(1);
+ if (power(7,3) != 343)
+ return(1);
+ if (power(7,4) != 2401)
+ return(1);
+ if (power(3,7) != 2187)
+ return(1);
+ if (power(2,10) != 1024)
+ return(1);
+ return(0);
+}
+#user
+cc tzaqc.c power.o
+a.out
+#succeed
+/* a possible solution */
+power(x, n)
+{
+ int k;
+
+ if (n < 0)
+ return(0);
+ if (n == 0)
+ return(1);
+ if (n%2 == 1)
+ return(x * power(x, n-1));
+ k = power(x, n/2);
+ return(k*k);
+}
+#log
+#next
+40.1a 10
diff --git a/usr.bin/learn/lib/C/L4.1a b/usr.bin/learn/lib/C/L4.1a
new file mode 100644
index 00000000000..e24f87438bc
--- /dev/null
+++ b/usr.bin/learn/lib/C/L4.1a
@@ -0,0 +1,10 @@
+#print
+Does the # of a "#define" statement absolutely
+have to go in column 1? Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#log
+#next
+5.1a 10
diff --git a/usr.bin/learn/lib/C/L40.1a b/usr.bin/learn/lib/C/L40.1a
new file mode 100644
index 00000000000..a5d67001df4
--- /dev/null
+++ b/usr.bin/learn/lib/C/L40.1a
@@ -0,0 +1,56 @@
+#print
+Write a subroutine
+ errmess(n)
+which looks at its argument and prints
+one of the following messages:
+ n message (follow it by a newline)
+ 1 ?
+ 2 syntax error
+ 3 bad syntax error
+ 4 fatal error
+ 5 I give up.
+anything else eh?
+Leave the routine on errmess.c, compiled and tested
+as usual. Then type "ready".
+#once #create Ref
+eh?
+eh?
+I give up.
+fatal error
+bad syntax error
+syntax error
+?
+#once #create tzaqc.c
+main()
+{
+ errmess (23069);
+ errmess (-2000);
+ errmess (5);
+ errmess (4);
+ errmess (3);
+ errmess (2);
+ errmess (1);
+}
+#user
+cc tzaqc.c errmess.o
+a.out >xxx
+#cmp Ref xxx
+#succeed
+/* a possible solution */
+char *message[] = {
+ "eh?",
+ "?",
+ "syntax error",
+ "bad syntax error",
+ "fatal error",
+ "I give up.",
+ };
+errmess(n)
+{
+ if (n < 0 || n > 5)
+ n = 0;
+ printf("%s\n", message[n]);
+}
+#log
+#next
+41.1a 10
diff --git a/usr.bin/learn/lib/C/L41.1a b/usr.bin/learn/lib/C/L41.1a
new file mode 100644
index 00000000000..bb85ecd59f1
--- /dev/null
+++ b/usr.bin/learn/lib/C/L41.1a
@@ -0,0 +1,67 @@
+#print
+The problem is to produce a function
+ bitct(x)
+which examines the bits in x, returning a count of
+the number of 1-bits. There are various ways of doing
+this job: here are two.
+(1) a sane way. Shift the word x right 16 times (you are
+on UNIX) and check the rightmost bit each time, counting
+the number of times it is '1'.
+(2) a machine-independent (sort of) way. The logical
+bitwise AND of x and x-1 contains one fewer one bit than x itself.
+Loop anding x and x-1 until you get zero.
+Program either algorithm. Compile and test it. Leave it on
+a file bitct.c and type "ready".
+#once #create tzaqc.c
+main()
+{
+ int x;
+ x=23069;
+ if (bitct(x) != goodct(x))
+ return(1);
+ x=0;
+ if (bitct(x) != goodct(x))
+ return(1);
+ x=16384;
+ if (bitct(x) != goodct(x))
+ return(1);
+ x = -1;
+ if (bitct(x) != goodct(x))
+ return(1);
+ x= -200;
+ if (bitct(x) != goodct(x))
+ return(1);
+ return(0);
+}
+goodct(x)
+{
+ int k, i;
+ for(k=i=0; i<16; i++)
+ {
+ k =+ (x&1);
+ x= x>>1;
+ }
+ return(k);
+}
+#user
+cc tzaqc.c bitct.o
+a.out
+#succeed
+/* a possible solution */
+bitct(x)
+{
+ int k, i;
+
+ for(i=k=0; i<16; i++) {
+ if (x&1)
+ k++;
+ x >>= 1;
+ }
+ return(k);
+}
+/* by the way, if you really care about
+this problem a table lookup by whole bytes
+is faster */
+#log
+#next
+42.1a 10
diff --git a/usr.bin/learn/lib/C/L42.1a b/usr.bin/learn/lib/C/L42.1a
new file mode 100644
index 00000000000..e5323840a9d
--- /dev/null
+++ b/usr.bin/learn/lib/C/L42.1a
@@ -0,0 +1,57 @@
+#print
+Write a function
+ inprod(a,b,n)
+that computes the inner product of two integer vectors
+a and b which are n items long. Name the file "inprod.c"
+and compile and test it; then type ready.
+You may assume that the result and all intermediate
+values fit in a 16-bit integer, not usually a safe assumption.
+#once #create tzaqc.c
+main()
+{
+ int x[100], y[100];
+ int k;
+ for(k=0; k<100; k++)
+ {
+ x[k] = k%10;
+ y[k] = (k*k)%3;
+ }
+ if (inprod(x,y,100) != xprod(x,y,100)) return(1);
+ return(0);
+}
+xprod(x,y,n)
+ int *x, *y;
+{
+ int k, sum;
+ for(sum=k=0; k<n; k++)
+ sum=+ *x++ * *y++;
+ return(sum);
+}
+#user
+cc tzaqc.c inprod.o
+a.out
+#succeed
+/* one way */
+inprod(a, b, n)
+int *a, *b;
+{
+ int s;
+
+ s = 0;
+ while (n--)
+ s += *a++ * *b++;
+
+/* none of the spaces in the line above are necessary but
+ would you really want to read
+ s+=*a++**b++;
+ and try to parse it? Even clearer than what I have,
+ but slower, would be
+ for(i=0; i<n; i++)
+ s += a[i]*b[i];
+*/
+
+ return(s);
+}
+#log
+#next
+43.1a 10
diff --git a/usr.bin/learn/lib/C/L43.1a b/usr.bin/learn/lib/C/L43.1a
new file mode 100644
index 00000000000..cd62075a88c
--- /dev/null
+++ b/usr.bin/learn/lib/C/L43.1a
@@ -0,0 +1,70 @@
+#print
+Write a function
+ cubrt(x)
+that returns the cube root of a floating point number.
+Put it on a file named "cubrt.c"; compile and test it,
+then type "ready".
+(If you don't know how to compute cube roots, try Newton's method).
+#once #create reldif.c
+double reldif(a,b)
+ double a,b;
+{
+double c,d;
+if (a==0. && b==0.) return(0.);
+c = a>0 ? a : -a;
+d = b>0 ? b : -b;
+c = c>d ? c : d;
+return( (a-b)/c );
+}
+#once #create tzaqc.c
+main()
+{
+ double cubrt();
+ double reldif();
+ double a, b, eps;
+
+ a = 8.;
+ b = 2.;
+ eps = 1e-5;
+ if (reldif(cubrt(a), b) > eps)
+ exit(1);
+
+ a = 0.;
+ b = 0.;
+ if (reldif(cubrt(a), b) > eps)
+ exit(1);
+
+ a = 1e6;
+ b = 1e2;
+ if (reldif(cubrt(a), b) > eps)
+ exit(1);
+ exit(0);
+}
+#user
+cc tzaqc.c cubrt.o reldif.c
+a.out
+#succeed
+/* one way */
+double cubrt(x)
+double x;
+{
+ /* Newton's method: x <- x - (x**3-a)/(3*x*x) */
+ double y, yn, dabs();
+ y = 0.;
+ yn = x;
+ while (dabs(y-yn) > y*1.e-8) {
+ y = yn;
+ yn = y - (y*y*y-x)/(3*y*y);
+ }
+ return(yn);
+}
+
+double dabs(x)
+double x;
+{
+ return(x>0 ? x : -x);
+}
+#log
+#next
+50.1a 10
+43.1b 5
diff --git a/usr.bin/learn/lib/C/L43.1b b/usr.bin/learn/lib/C/L43.1b
new file mode 100644
index 00000000000..85f89612dd4
--- /dev/null
+++ b/usr.bin/learn/lib/C/L43.1b
@@ -0,0 +1,67 @@
+#print
+Write a subroutine myexp(x) which expects a floating
+argument x and returns the floating point value
+of e to the x. An adequate algorithm
+for the purpose is the standard Maclaurin series
+
+ x 2 3 4
+ e = 1 + x + x /2! + x /3! + x /4! + ...
+Name your routine myexp(), not exp(). You can test it, then,
+by comparing it with the system routine as well as by
+comparing it with tables. Leave it on file
+myexp.c, and then type "ready".
+#once #create reldif.c
+double reldif(a,b)
+ double a,b;
+{
+double c,d;
+if (a==0. && b==0.) return(0.);
+c = a>0 ? a : -a;
+d = b>0 ? b : -b;
+c = c>d ? c : d;
+return( (a-b)/c );
+}
+#once #create tzaqc.c
+main()
+{
+double x,y, log(), myexp(), reldif();
+for(x=1.; x<5.; x=+ 0.2)
+ {
+ y = myexp(x);
+ if (reldif(x, log(y)) >1.e-5) return(1);
+ }
+return(0);
+}
+exp()
+{
+printf("Cheat! you called the system routine\n");
+return(1.2);
+}
+#user
+cc tzaqc.c myexp.o reldif.c
+a.out
+#succeed
+/* one way */
+double myexp(x)
+double x;
+{
+ double term, sum, dabs();
+ int n;
+
+ term = sum = 1.0;
+ n = 1;
+ while (dabs(term) > dabs(sum)/1.e8) {
+ term = term * x / n++;
+ sum += term;
+ }
+ return(sum);
+}
+
+double dabs(x)
+double x;
+{
+ return(x>0 ? x : -x);
+}
+#log
+#next
+50.1a 10
diff --git a/usr.bin/learn/lib/C/L5.1a b/usr.bin/learn/lib/C/L5.1a
new file mode 100644
index 00000000000..9fcae1cb08e
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.1a
@@ -0,0 +1,26 @@
+#print
+(Section 1.5)
+Write a program that copies exactly three characters
+from its input to its output.
+When compiled and tested, type ready.
+#once #create Ref
+XY
+#once #create z1
+XY
+marks the spot.
+#user
+a.out <z1 >z2
+#cmp z2 Ref
+#succeed
+/* Here is one possible solution */
+
+main()
+{
+ putchar(getchar());
+ putchar(getchar());
+ putchar(getchar());
+}
+#log
+#next
+5.1b 10
+5.2a 5
diff --git a/usr.bin/learn/lib/C/L5.1b b/usr.bin/learn/lib/C/L5.1b
new file mode 100644
index 00000000000..e6954bfa915
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.1b
@@ -0,0 +1,25 @@
+#print
+(Section 1.5)
+Write a program that will read the first character
+from its input and print it out in octal.
+Compile it, test it, and then type ready.
+#once #create Ref
++
+#user
+a.out <Ref >test
+grep 53 test >/dev/null
+#succeed
+A possible solution:
+
+main()
+{
+ printf("%o\n", getchar());
+}
+
+ Remember that you can use a function value almost
+ any place that you could use a variable like x.
+ Thus many times there's no need for extra variables.
+#log
+#next
+5.1c 10
+5.2b 5
diff --git a/usr.bin/learn/lib/C/L5.1c b/usr.bin/learn/lib/C/L5.1c
new file mode 100644
index 00000000000..44c3f59060c
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.1c
@@ -0,0 +1,31 @@
+#print
+(Section 1.5)
+Write a program which reads one character from
+its input; if that character is ? it prints "yes",
+otherwise it prints "no".
+Compile it, test it, and then type ready.
+#once #create Ref1
+? is here
+#once #create Ref2
+no ? at beginning
+#user
+a.out <Ref1 >test1
+a.out <Ref2 >test2
+grep yes test1 >/dev/null && grep no test2 >/dev/null
+#succeed
+This is one possible solution
+
+main()
+{
+ if (getchar() == '?')
+ printf("yes\n");
+ else
+ printf("no\n");
+}
+
+The indenting and general formatting of C programs
+should be done so you make the structure clear,
+like the code above.
+#log
+#next
+5.1d 10
diff --git a/usr.bin/learn/lib/C/L5.1d b/usr.bin/learn/lib/C/L5.1d
new file mode 100644
index 00000000000..bfa7289a452
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.1d
@@ -0,0 +1,48 @@
+#print
+Write a program that counts the blanks, tabs, and newlines
+in its input, and prints the total. Don't forget to
+define the value of EOF at the beginning of your program.
+The best way is to add
+
+ #include <stdio.h>
+
+as the first line of your program.
+The must____ be in column 1.
+(See page 143 of the C book.)
+You may also have to say
+
+cc name.c -lS
+
+to compile the program.
+#once #create Ref
+This is some junk that
+contains
+ blanks
+ tabs
+ and newlines.
+#user
+a.out <Ref >test1
+a.out </dev/null >test2
+grep 13 test1 >/dev/null && grep 0 test2 >/dev/null
+#succeed
+One possible solution:
+
+ #include <stdio.h>
+
+main()
+{
+ int n, c;
+
+ n = 0;
+ while ((c = getchar()) != EOF)
+ if (c == ' ' || c == '\t' || c == '\n')
+ n++;
+ printf("%d\n", n);
+}
+
+This program won't work on huge files, because an int
+isn't big enough.
+#log
+#next
+5.1e 10
+5.2e 5
diff --git a/usr.bin/learn/lib/C/L5.1e b/usr.bin/learn/lib/C/L5.1e
new file mode 100644
index 00000000000..47b100a83f6
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.1e
@@ -0,0 +1,31 @@
+#print
+Write a program that counts the number of vowels
+in its input (excluding 'y'). Don't forget to define
+the value of EOF at the beginning of your program.
+#once #create Ref
+This line contains some vowels, including
+the letter 'y'. It also has a capital letter, I think.
+#user
+a.out <Ref >test
+grep 28 test >/dev/null
+#succeed
+Here is one solution.
+
+ #include <stdio.h>
+
+main()
+{
+ int nv, c;
+
+ nv = 0;
+ while ((c = getchar()) != EOF)
+ if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u'
+ || c=='A' || c=='E' || c=='I' || c=='O' || c=='U')
+ nv++;
+ printf("%d\n", nv);
+}
+#fail
+Did you remember capital letters?
+#log
+#next
+5.1f 10
diff --git a/usr.bin/learn/lib/C/L5.1f b/usr.bin/learn/lib/C/L5.1f
new file mode 100644
index 00000000000..7ca40a0a7ca
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.1f
@@ -0,0 +1,17 @@
+#print
+(Section 1.5)
+Write a program to replace each tab by the
+three-character sequence >, backspace, -,
+which prints as ->. The program should also replace
+each backspace by the analogous sequence <-.
+Compile it, test it, then type ready.
+#once #create Ref
+This contain s a back space and a tab.
+#once #create Ref1
+This contain <-s a back <-space and a>-tab.
+#user
+a.out <Ref >test
+#cmp test Ref1
+#log
+#next
+5.1g 10
diff --git a/usr.bin/learn/lib/C/L5.1g b/usr.bin/learn/lib/C/L5.1g
new file mode 100644
index 00000000000..73ea4994661
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.1g
@@ -0,0 +1,38 @@
+#print
+Write a program to copy its input to its output,
+replacing each string of one or more blanks by
+a single blank.
+#once #create Ref
+ This has lines with several blanks
+including some in funny places.
+#once #create Ref1
+
+#once #create Answer
+ This has lines with several blanks
+including some in funny places.
+
+#user
+a.out <Ref >test
+a.out <Ref1 >>test
+#cmp test Answer
+#succeed
+One way:
+
+ #include <stdio.h>
+
+main()
+{
+ int c;
+
+ for (c = getchar(); c != EOF; ) {
+ putchar(c);
+ if (c == ' ')
+ while ((c = getchar()) == ' ')
+ ;
+ else
+ c = getchar();
+ }
+}
+#log
+#next
+9.1a 10
diff --git a/usr.bin/learn/lib/C/L5.2a b/usr.bin/learn/lib/C/L5.2a
new file mode 100644
index 00000000000..060e29c41b0
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.2a
@@ -0,0 +1,27 @@
+#print
+Write a program which reads a character from its
+input and prints "high" if that character is
+larger than 100 in numeric value (decimal) and "low"
+if it is less than or equal to 100 in numeric value.
+Compile it as usual and then type "ready".
+#once #create Ref1
+u is a big letter
+#once #create Ref2
+B is a small letter
+#user
+a.out <Ref1 >test1
+a.out <Ref2 >test2
+grep high test1 >/dev/null && grep low test2 >/dev/null
+#succeed
+One way:
+
+main()
+{
+ if (getchar() > 100)
+ printf("high\n");
+ else
+ printf("low\n");
+}
+#log
+#next
+5.1b 10
diff --git a/usr.bin/learn/lib/C/L5.2b b/usr.bin/learn/lib/C/L5.2b
new file mode 100644
index 00000000000..0fce2989e27
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.2b
@@ -0,0 +1,28 @@
+#print
+(Section 1.5)
+Write a program which reads a character from its
+input and tests whether that character is larger than
+100 in numeric value. If so, read two more
+characters, and print the value of the second of them
+in octal. Compile and test your program, then type "ready".
+#once #create Ref1
+u V has value 126
+#once #create Ref2
+. V should not be processed
+#user
+a.out <Ref1 >test1
+a.out <Ref2 >test2
+grep 126 test1 >/dev/null && cmp -s test2 /dev/null
+#succeed
+One way:
+
+main()
+{
+ if (getchar() > 100) {
+ getchar();
+ printf("%o\n", getchar());
+ }
+}
+#log
+#next
+5.1c 10
diff --git a/usr.bin/learn/lib/C/L5.2e b/usr.bin/learn/lib/C/L5.2e
new file mode 100644
index 00000000000..987a3cdb127
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.2e
@@ -0,0 +1,58 @@
+#print
+(Section 1.5)
+Write a program which copies its input to its output
+doubling each character (i.e. each input character
+is written twice on the output). Compile and test
+it. Then type ready. Don't forget
+
+ #include <stdio.h>
+
+at the beginning of your program, and
+
+cc x.c -lS
+
+to compile it.
+#once #create Ref
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+gillette stirling millington lyons basking ridge
+bernardsville far hills peapack gladstone
+#once #create Answer
+hhoobbookkeenn hhaarrrriissoonn nneewwaarrkk rroosseevviillllee aavveennuuee ggrroovvee ssttrreeeett
+
+eeaasstt oorraannggee bbrriicckk cchhuurrcchh oorraannggee hhiigghhllaanndd aavveennuuee
+
+mmoouunnttaaiinn ssttaattiioonn ssoouutthh oorraannggee mmaapplleewwoooodd mmiillllbbuurrnn sshhoorrtt hhiillllss
+
+ssuummmmiitt cchhaatthhaamm mmaaddiissoonn ccoonnvveenntt ssttaattiioonn mmoorrrriissttoowwnn
+
+nneeww pprroovviiddeennccee mmuurrrraayy hhiillll bbeerrkkeelleeyy hheeiigghhttss
+
+ggiilllleettttee ssttiirrlliinngg mmiilllliinnggttoonn llyyoonnss bbaasskkiinngg rriiddggee
+
+bbeerrnnaarrddssvviillllee ffaarr hhiillllss ppeeaappaacckk ggllaaddssttoonnee
+
+#user
+a.out <Ref >xxx
+#cmp Answer xxx
+#succeed
+/* One way: */
+
+ #include <stdio.h>
+
+main()
+{
+ int c;
+
+ while ((c = getchar()) != EOF) {
+ putchar(c);
+ putchar(c);
+ }
+}
+#log
+#next
+5.1e 5
+5.3e 2
diff --git a/usr.bin/learn/lib/C/L5.3e b/usr.bin/learn/lib/C/L5.3e
new file mode 100644
index 00000000000..32004967013
--- /dev/null
+++ b/usr.bin/learn/lib/C/L5.3e
@@ -0,0 +1,28 @@
+#print
+Write a program which copies its input to
+its output. Compile and test it. Then type ready.
+#once #create Ref
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+gillette stirling millington lyons basking ridge
+bernardsville far hills peapack gladstone
+#user
+a.out <Ref >xxx
+#cmp Ref xxx
+#succeed
+/* One way: */
+
+ #include <stdio.h>
+
+main() {
+ int c;
+
+ while ((c = getchar()) != EOF)
+ putchar(c);
+}
+#log
+#next
+5.1e 10
diff --git a/usr.bin/learn/lib/C/L50.1a b/usr.bin/learn/lib/C/L50.1a
new file mode 100644
index 00000000000..085ea65faf6
--- /dev/null
+++ b/usr.bin/learn/lib/C/L50.1a
@@ -0,0 +1,145 @@
+#print
+(Everything)
+Write a program that reads an input file and
+prints out the most frequently appearing word in it.
+Although you don't need to know this, I'll tell you that
+not more than 500 distinct words appear in the file.
+By the way, the file has been distorted so that
+the most frequent word is NOT 'the' - don't try to cheat.
+Compile and test your program.
+#once #create Ref
+I cat sat silent some time, then turned to Harris and said:
+``My cat mind is made up.''
+Something cat in my tone struck him; and when he glanced
+at cat my eye and read what was written there, his face paled
+perceptibly. cat He hesitated a moment, then said:
+``Speak.''
+I cat answered, with perfect calmness:
+``I cat WILL ASCEND THE RIFFELBERG.''
+If cat I had shot my poor friend he could not have fallen from
+his cat chair more suddenly. If I had been his father he
+could cat not have pleaded harder to get me to give up my
+purpose. cat But I turned a deaf ear to all he said. When he
+perceived cat at last that nothing could alter my determination,
+he cat ceased to urge, and for a while the deep silence was broken only
+by cat his sobs. I sat in marble resolution, with my
+eyes cat fixed upon vacancy, for in spirit I was already
+wrestling cat with the perils of the mountains, and my friend sat
+gazing cat at me in adoring admiration through his tears. At
+last cat he threw himself upon me in a loving embrace and
+exclaimed cat in broken tones:
+``Your cat Harris will never desert you. We will die together!''
+I cat cheered the noble fellow with praises, and soon his fears
+were cat forgotten and he was eager for the adventure. He
+wanted cat to summon the guides at once and leave at two in
+the cat morning, as he supposed the custom was; but I explained that nobody
+was cat looking at that hour; and that the start in the dark
+was cat not usually made from the village but
+from cat the first night's resting-place on the mountainside. I
+said cat we would leave the village at 3 or 4 p.m. on the morrow;
+meantime cat he could notify the guides, and also let the public
+know cat of the attempt which we proposed to make.
+I cat went to bed, but not to sleep. No man can sleep when
+he cat is about to undertake one of these Alpine exploits. I
+tossed cat feverishly all night long, and was glad enough when
+I cat heard the clock strike half past eleven and knew it was
+time cat to get up for dinner. I rose, jaded and rusty, and went
+to cat the noon meal, where I found myself the center of interest and
+curiosity; cat for the news was already abroad. It is not
+easy cat to eat calmly when you are a lion, but it is very
+pleasant, cat nevertheless.
+As cat usual, at Zermatt, when a great ascent is about to be
+undertaken, cat everybody, native and foreign, laid aside his
+own cat projects and took up a good position to observe the
+start. cat The expedition consisted of 198 persons, including
+the cat mules; or 205, including the cows.
+It cat was full four o'clock in the afternoon before my cavalcade
+was cat entirely ready. At that hour it began to move. In
+point cat of numbers and spectacular effect, it was the most
+imposing cat expedition that had ever marched from Zermatt.
+I cat commanded the chief guide to arrange the men and
+#user
+a.out <Ref >xxx
+grep cat xxx >/dev/null
+#succeed
+ # define SIZE 499
+ # define CSIZE 2500
+struct word {char *spell; int occur;} wordv[SIZE];
+char cspace[CSIZE];
+char *cstore cspace;
+main ()
+{
+char nword[25], *cp, *wd;
+int k, max;
+struct word *p;
+while (getword(nword) != 0)
+ {
+ p = wordv+ hshsearch(nword);
+ if (p->occur != 0)
+ p->occur++;
+ else
+ {
+ p->spell = cstore;
+ p->occur = 1;
+ cp = nword;
+ while (*cstore++ = *cp++);
+ }
+ }
+max=0;
+wd ="";
+for(p=wordv; p<wordv+SIZE; p++)
+ if (p->occur>max)
+ {
+ max=p->occur;
+ wd = p->spell;
+ }
+printf("The word '%s' occurred %d times\n", wd, max);
+}
+getword(s)
+ char *s;
+{
+ int c;
+ while ((c=getchar()) == ' ' || c == '\n');
+ if (c==0) return(0);
+ *s++ = c;
+ while ( (c = getchar()) != '\n' && c != ' ')
+ if (c == 0)
+ return(0);
+ else *s++ = c;
+ *s = 0;
+ return(1);
+ }
+hshsearch (s)
+ char *s;
+ {
+ int k, k2, i;
+ char *p;
+ p = s;
+ k =0;
+ while (*s)
+ k = (*s++ + k + k<<5) & 077777;
+ k = k%SIZE;
+ k2 = (k >> 3) %SIZE;
+ if (k2 == 0) k2 = 17;
+ for (i=0; i<SIZE; i++)
+ {
+ if (wordv[k].occur == 0)
+ return(k);
+ if (comp(wordv[k].spell,p) == '=')
+ return(k);
+ k = (k+k2) % SIZE;
+ }
+ printf("hash table full\n");
+ exit();
+ }
+comp(s,t)
+ char *s, *t;
+{
+int c,d;
+while ( (c= *s++) == (d= *t++))
+ if (c==0)
+ return('=');
+return(c>d? '>': '<');
+}
+#log
+#next
diff --git a/usr.bin/learn/lib/C/L9.1a b/usr.bin/learn/lib/C/L9.1a
new file mode 100644
index 00000000000..fc2c1cd407e
--- /dev/null
+++ b/usr.bin/learn/lib/C/L9.1a
@@ -0,0 +1,33 @@
+#print
+(Section 1.9 -- read 1.6-1.8 too.)
+Write a program that removes trailing blanks
+and tabs from each line of input, and deletes
+entirely blank lines. To make your job easier,
+you can use the function getline; its source
+is in getline.c.
+Type read when you are done.
+#once #create Ref
+ This file contains
+some trailing
+blanks
+and tabs
+
+
+
+
+and some empty lines.
+#once #create Ref1
+ This file contains
+some trailing
+blanks
+and tabs
+and some empty lines.
+#once cp %s/getline.c .
+#user
+a.out <Ref >test
+#cmp test Ref1
+#succeed
+No answer yet - sorry.
+#log
+#next
+10 10
diff --git a/usr.bin/learn/lib/C/getline.c b/usr.bin/learn/lib/C/getline.c
new file mode 100644
index 00000000000..8d24aa2b783
--- /dev/null
+++ b/usr.bin/learn/lib/C/getline.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+getline(s, lim) /* get line into s, return length */
+char s[];
+int lim;
+{
+ int c, i;
+
+ i = 0;
+ while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
+ s[i++] = c;
+ if (c == '\n')
+ s[i++] = c;
+ s[i] = '\0';
+ return(i);
+}
diff --git a/usr.bin/learn/lib/C/getnum.c b/usr.bin/learn/lib/C/getnum.c
new file mode 100644
index 00000000000..1bb379ee75d
--- /dev/null
+++ b/usr.bin/learn/lib/C/getnum.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+getnum()
+{
+ int c, n;
+
+ n = 0;
+ while ((c=getchar()) >= '0' && c <= '9')
+ n = n*10 + c - '0';
+ if (c == EOF)
+ return(-1);
+ return(n);
+}