C code in ubuntu

COMP 2103X1 Assignment 2 Due Thursday, January 26 by 7:00 PM General information about assignments ( important!):

http://cs.acadiau.ca/ ~jdiamond/comp2103/assignments/General-info.html Information on passing in assignments:

http://cs.acadiau.ca/ ~jdiamond/comp2103/assignments/Pass-in-info.html Information on coding style:

http://cs.acadiau.ca/ ~jdiamond/comp2103/assignments/C-coding-style-notes [1] A lterprogram is a program which reads its input from “standard input” (“stdin”) and writes its output to “standard output” (“stdout”). Filter programs are useful because they make it easy to combine the functions they provide to solve more complex problems using the standard shell facilities. Filter programs are also nice to write, because the programmer doesn't have to worry about writing code to open and close les, nor does the programmer have to worry about dealing with related error conditions. In some respects, lter programs are truly “win­win”.

Write a lter program which uses getchar()to read in characters from stdin, continuing until end of le (read the manpage and/or textbook to see the details on getchar(), or, heaven forbid, review the class slides). Your program must count the number of occurrences of each character in the input. After having read all of the input, it outputs a table similar to the one below which, for each character seen at least once, lists the total number of times that character was seen as well as its relative frequency (expressed as a percentage). Note that the characters , , ,\0 ,\a ,\b , \f , and \v(see man ascii ) must be displayed with the appropriate “escape sequence”. Ordinary printable characters must be output as themselves. Non­printable characters (see man isprint) must be printed with their three­digit octal code (see man printf).

You can get input into a lter program ( a2p1in this case) in three ways:

(a) “pipe” data from another program into it, like $echo blah blah | a2p1 (b) “redirect” the contents of a le into the program, like $a2p1 < some-file (c) type at the keyboard, and (eventually) type ^D(control­d) at the beginning of a line to signify end of le.

Your output must look like the following, for this sample case: $echo ^Aboo | a2p1 Char Count Frequency -------------------------- 001 1 20.00% 1 20.00%b 1 20.00% o 2 40.00% Note: in the above examples, and from now on in this course's assignments, text inredis text that the human types, and a “ $" at the beginning of a line like that represents the shell prompt.

1 Note that I entered a ^A(control­a, notthe circum ex character followed by the capital A) by typing ^V^A. The ^Vtells your shell that you want it to interpret the next character literally, rather than to use any special meaning (during command line entry) that the next character might normally have. (Question: what does your shell do, when typing in a command line, if you type ^Awithout rst entering ^V? Try it and see if you can gure it out. You might nd it useful to know this, and to know what ^Eand ^Wdo as well.) You should run your program on a few different inputs to demonstrate to the marker that you have thought about (and programmed for!) the different cases that could occur. If you redirect input from a data le, rather than using “ cat” to display the contents of your le when creating your transcript le, use a command like $od -bc test-data-1.

[2] The printf() function in C is very powerful and convenient, but it takes some getting used to.

This question will give you experience with this function.

When you are testing functions like printf()which produce formatted output, sometimes you want to make sure that the spaces in the output are the ones you expect. To make it obvious where all the white space came from, it is often convenient to enclose a format speci cation inside a pair of characters that are not otherwise used in that output. For example, if you use something like printf("|%f| ", x) then you will know whether the %fformat speci cation produced any spaces before the newline.

The constant M_PI, an approximation to the value of , is de ned in the system include le math.h.

Write a program which prints out the value of M_PIusing each of the following speci cations, one speci cation per line of output: (a) xed point notation, eld width of 9, 5 digits of precision, left justi ed (b) xed point notation, eld width of 9, 5 digits of precision, right justi ed (c) xed point notation, eld width of 9, no precision speci cation, right justi ed (d) xed point notation, eld width unspeci ed, 5 digits of precision, right justi ed (e) scienti c notation, eld width 9, 5 digits of precision, right justi ed (f) scienti c notation, eld width 9, 5 digits of precision, left justi ed (g) scienti c notation, eld width 14, 5 digits of precision, right justi ed (h) scienti c notation, eld width 14, 5 digits of precision, left justi ed As an example of what your output might look like, here is one sample line of output: |3.14159 | is field 9, precision 5, left justified Examine your output and try to understand what the printf()function is doing, especially any outputs that you nd surprising.

2 [3] These days, many people are very concerned with the protection of private information. This program will do a very rudimentary form of encryption. (Don't use this for anything you want to keep secret!) Write a lter program to encrypt standard input as follows:

(i) upper case letters between `A' and `M' are replaced with the lower case letter 13 positions further along in the alphabet (e.g., `B' is replaced with `o'); (ii) upper case letters between `N' and `Z' are replaced with the lower case letter 13 positions earlier in the alphabet (e.g., `Z' is replaced with `m'); (iii) lower case letters between `a' and `m' are replaced with the upper case letter 13 positions further along in the alphabet (e.g., `d' is replaced with `Q'); (iv) lower case letters between `n' and `z' are replaced with the upper case letter 13 positions earlier in the alphabet (e.g., `y' is replaced with `L'); (v) the four punctuation characters `.', `,', `!' and `?' are replaced with, respectively, `!', `?', `.' and `,'.

Of course, an encryption program is no use without a corresponding decryption program. A bit of thought (or experimentation) should show that this program will decrypt its own output.

To test your program, create a few text les; some small, some big. Then run some tests which will convince the marker of the following things:

(i) the output of the program looks different than the input; and (ii) running the output of the program through the program a second time recovers the original data.

You can make use of the Unix utilities diffand/or cmp, as well as cat, to help convince the marker that your program works. Here is a sample run with a small number of tests. Note that you don't need to catbig les into the script le, but you can use ls -lorwc to show the marker that the les were big.

$ $ $cat test1.dat This is a short file.

Is it long enough, or should it be longer?

$ $a3p1 < test1.dat gUVF VF N FUBEG SVYR!

vF VG YBAT RABHTU? BE FUBHYQ VG OR YBATRE, $ $a3p1 < test1.dat | a3p1 This is a short file.

Is it long enough, or should it be longer?

$ $wc test2.dat 1241 3394 44616 test2.dat $a3p1 < test2.dat > test2.dat.crypt 3 $ $wc test2.dat.crypt 1241 3394 44616 test2.dat.crypt $ $cmp test2.dat test2.dat.crypt test2.dat test2.dat.crypt differ: byte 3, line 1 $ $a3p1 < test2.dat.crypt > test2.dat.crypt.decrypt $ $cmp test2.dat test2.dat.crypt.decrypt $ Notice that, as is common for Unix programs, cmpsays nothing in the “success” case, which for cmp is when the two les are identical.

The third (red) command entered above is interesting. It shows how the Unix shell (command interpreter) allows you to send the output of one program (the rst a2p3) into the input to another program (in this case the second a2p3). This is an extremely powerful feature of the shell, especially since your program does not have to do anything special to make this happen; as far as your program is concerned, it is reading from standard input and writing to standard output. The fact that those may be the keyboard, screen, a le or another program generally don't matter to your program. (In fact, the occasional program does care, but that is an uncommon circumstance.) In the partial script above I showed a test with a short le, and a long le. I showed that (some) letters got encrypted as they should, and that punctuation is properly encrypted. I also showed that my program works with a fairly long le, but you might want to try a bigger le yet. And you might consider using the headprogram to output just the rst few lines of a very long le to your script le.

Should anything else be tested? Are there any boundary cases here? Did you use functions in any of these questions? Should you have? Did you document them correctly?

Does you program “blow up” on unexpected input, or does it deal with bad input in a “graceful” way?

How does your program deal with boundary conditions, if there are any?

Did you remember to put all required comments in? Does your program call out for any other comments in the body of the code?

4