The purpose of this assignment is to help you learn or review (1)
the fundamentals of the C programming language, (2) a portion of the
"de-commenting" task of the C preprocessor, and (3) use of the
GNU/Unix programming tools,
especially bash
, vscode
(or any editor of your choice),
and gcc209
.
Make sure you study the course policy web page before doing this assignment or any of the EE 209 assignments. In particular, note that you may consult with the course instructors, lab TAs, mailing list, etc. while doing assignments, as prescribed by that web page. However, there is one exception...
Throughout the semester, each assignment will have an "on your own" part. You must do that part of the assignment completely on your own, without consulting with the course instructors, lab TAs, mailing list, etc., except for clarification of requirements. You might think of the "on your own" part of each assignment as a small take-home exam.
Your task is to write a C program named wc209
that
prints the number of newlines, words, and characters in the input text
fed from standard input to standard ouput. The program behaves
similarly to Linux wc
, but wc209
skips
"commented text"(e.g., text in /* ... */
, text behind //...
) and does not
count such text in the output.
Your program should read characters from the standard input stream, and write the output to the standard output stream . Specifically, your program should (1) read text from the standard input stream, (2) write the number of newlines, words, and characters in the input text to the standard output stream with block and line comment replaced by a space and an empty string respectively. A typical execution of your program from a shell might look like this:
The output (3 13 300
) indicates that there are 3 newlines,
13 words, and 300 characters in the file, somefile.txt
.
Here are a few rules.
isspace()
-- space, form-fead ('\f'), newline('\n'), carriage
return ('\r'), horizontal tab('\t'), and vertical tab ('\v').
0 0 0
.
In the following examples a space character is shown as
"s
" and a newline character as
"n
".
Your program should internally consider each comment, which starts with /* and ends with */, as a space. Examples:
Standard Input Stream | Internal Representation After Decommenting | Standard Output Stream |
---|---|---|
abc/*def*/ghin
|
abcsghin
|
1s2s8n
|
abc/*def*/sghin
|
abcssghin
|
1s2s9n
|
abcs/*def*/ghin
|
abcssghin
|
1s2s9n
|
Your program should count the number of newlines.
Standard Input Stream | Internal Representation After Decommenting | Standard Output Stream |
---|---|---|
abc
|
abc
|
0s1s3n
|
abcndef
|
abcndef
|
1s2s7n
|
Your program should define a "comment" as in the C99 standard. In
particular, your program also should consider line comment
of the form (//...
).
Example:
Standard Input Stream | Internal Representation After Decommenting | Standard Output Stream |
---|---|---|
abc//defn
|
abcn
|
1s1s4n
|
abc//def
|
abc
|
0s1s3n
|
Your program should allow a comment to span multiple lines. That is, your program should allow a comment to contain newline characters. Your program should add blank lines as necessary to preserve the original line numbering. Also, each newline character in a comment is counted as one character. Examples:
Standard Input Stream | Internal Representation After Decommenting | Standard Output Stream |
---|---|---|
abc/*defnghi*/jklnmnon
|
abcsnjklnmnon
|
3s3s13n
|
abc/*defnghinjkl*/mnonpqrn
|
abcsnnmnonpqrn
|
4s3s14n
|
abc//defnghinmnon
|
abcnghinmnon
|
3s3s12n
|
Your program should not recognize nested comments. Example:
Standard Input Stream | Internal Representation After Decommenting | Standard Output Stream |
---|---|---|
abc/*def/*ghi*/jkl*/mnon
|
abcsjkl*/mnon
|
1s2s13n
|
abc//def/*ghin*/jkln
|
abcn*/jkln
|
2s2s10n
|
Your word counting program should handle unterminated comment case.
This is an example of unterminated comment:
stdio.h
header, and use:At the end of your main function, your program should
return EXIT_SUCCESS
or, equivalently 0. Note that
EXIT_SUCCESS
is defined in the standard header
file, stdlib.h
.
Your program should work for standard input lines of any length whose number of characters is less than 2 billion characters.
Design your program as a deterministic finite state automaton (DFA, alias FSA). The DFA concept is described in lectures, and in Section 5.1 of the book Introduction to Programming (Sedgewick and Wayne). That book section is available through the web at http://introcs.cs.princeton.edu/java/51language/.
We suggest that your program use the standard C getchar
function to read characters from the standard input stream.
You should create your program on the lab machines cluster using bash
, vscode
(or any editor of your choice), and gcc209
.
You are only allowed to use the following libraries in your program: <stdio.h>, <ctype.h>, <assert.h>, <stdlib.h>, and <stdbool.h>.
Express your DFA using the traditional "ovals and labeled arrows" notation. More precisely, use the same notation as is used in the examples from Section 5.1 of the Sedgewick and Wayne book. Let each oval represent a state. Give each state a descriptive name. Let each arrow represent a transition from one state to another. Label each arrow with the character, or class of characters, that causes the transition to occur. We encourage (but do not require) you also to label each arrow with action(s) that should occur (e.g. "print the character") when the corresponding transition occurs.
Express as much of the program's logic as you can within your DFA. The more logic you express in your DFA, the better your grade on the DFA will be.
Use any editor (e.g., vscode
) to create source code in a file named wc209.c
that implements your DFA.
Use the gcc209
command to preprocess, compile, assemble, and link your program. Perform each step individually, and examine the intermediate results to the extent possible.
Execute your program multiple times on various input files that test all logical paths through your code.
We have provided several files that you require for this assignment.
(1) Download a tar.gz file to your directory.
You will find samplewc209
, test files, and several utilities.
(2) samplewc209
is an executable version of a correct assignment solution. Your program should write exactly (character for character) the same data to the standard output stream as samplewc209
does. You should test your program using commands similar to these:
The Unix diff
command finds
differences between two given files. diff output1
output2
produces output, then samplewc209
and your
program have written different characters to the standard output
stream.
You also can test your program against its own source code using a command sequence such as this:
readme
File and an Ethics documentUse an editor to create a text file named readme
(not readme.txt
, or README
, or Readme
, etc.) that contains:
Descriptions of your code should not be in the readme
file. Instead they should be integrated into your code as comments.
Your readme
file should be a plain text file. Don't create your readme
file using Microsoft Word, Hangul (HWP) or any other word processor.
For every assignment submission, you must submit your own Ethics document that pledges that you did not violate any rules of course policy or any rules of ethics enforced by KAIST while doing this assignment.
Please edit an Ethics document for assignment 1 and submit it along with other files. Please write the assignment number, your name, sign on it, and make it into a PDF file (you can convert it into the PDF format in the FILE menu of MS Word).
Your submission should include your wc209.c
file and your readme
file.
Also submit your DFA. Create your "labeled ovals and labeled arrows" DFA and make it in a PDF file. A DFA drawn using drawing software (e.g. Microsoft PowerPoint) would be best. But it is sufficient to submit a photo of a neatly hand-drawn DFA. Make sure you convert the file into a PDF file.
Please name the DFA file dfa.pdf
(not dfa.txt
, DFA
, DFA.jpg
, DFA.png
,etc.)
We cannot accept your DFA via e-mail.
Create a local directory named 'YourID_assign1
' and place all your files in it. Then, tar
your submission file by issuing the following command on a lab machine (assuming your ID is 20241234):
Upload your submission file (20241234_assign1.tar.gz) to our KLMS assignment submission link. We do not accept e-mail submission (unless KLMS is down).
Please follow the same procedure for the future assignments.
Your submission file should look like this:
STUDENT_ID
in your project directory with your student id.
Then, use a given script to check your submission file before you submit.We will grade your work on two kinds of quality: quality from the user's point of view, and quality from the programmer's point of view. To encourage good coding practices, we will deduct points if gcc209
generates warning messages.
From the user's point of view, a program has quality if it behaves as it should. The correct behavior of your program is defined by the previous sections of this assignment specification, and by the behavior of the given samplewc209
program.
From the programmer's point of view, a program has quality if it is well styled and thereby easy to maintain. In part, style is defined by the rules given in The Practice of Programming (Kernighan and Pike), as summarized by the Rules of Programming Style document. For this assignment we will pay particular attention to rules 1-24. These additional rules apply:
c
might indicate that the variable is of type char
, i
might indicate int
, pc
might mean char*
, ui
might mean unsigned int
, etc. But it is fine to use another style -- a style that does not include the type of a variable in its name -- as long as the result is a clear and readable program.main
function -- should begin with a comment that describes what the function does from the point of view of the caller. (The comment should not describe how the function works.) It should do so by explicitly referring to the function's parameters and return value. The comment also should state what, if anything, the function reads from the standard input stream or any other stream, and what, if anything, the function writes to the standard output stream, the standard error stream, or any other stream. Finally, the function's comment should state which global variables the function uses or affects. In short, a function's comments should describe the flow of data into and out of the function.main
function. Instead your program should consist of multiple small functions, each of which performs a single well-defined task. For example, you might create one function to implement each state of your DFA.As prescribed by Kernighan and Pike style rule 25, generally you should avoid using global variables. Instead all communication of data into and out of a function should occur via the function's parameters and its return value. You should use ordinary call-by-value parameters to communicate data from a calling function to your function. You should use your function's return value to communicate data from your function back to its calling function. You should use call-by-reference parameters to communicate additional data from your function back to its calling function, or as bi-directional channels of communication.
However, call-by-reference involves using pointer variables, which we have not discussed yet. So for this assignment you may use global variables instead of call-by-reference parameters. (But we encourage you to use call-by-reference parameters.)
In short, you should use ordinary call-by-value function parameters and function return values in your program as appropriate. But you need not use call-by-reference parameters; instead you may use global variables. In subsequent assignments you should use global variables only when there is a good reason to do so.