From 82d318879c897b3d665767d74806cd33fe6791c0 Mon Sep 17 00:00:00 2001 From: zlg Date: Tue, 23 Apr 2013 13:33:25 -0500 Subject: Add exercise descriptions and answers for ch1 * Corrected behavior in solutions for 1-9 and 1-23 --- ch1/1-23_decomment.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'ch1/1-23_decomment.c') diff --git a/ch1/1-23_decomment.c b/ch1/1-23_decomment.c index 63193cd..d9c5c90 100644 --- a/ch1/1-23_decomment.c +++ b/ch1/1-23_decomment.c @@ -1,28 +1,29 @@ #include /* The C Programming Language: 2nd Edition - * Exercise 1-23: - * "Write a program to remove all comments from a C program. Don't forget to - * handle quoted strings and character constants properly. C comments do not - * nest." * - * I'm not sure why the instructions tell the reader to account for quoted - * strings and character constants. Comments always begin with either // or - * /*, so that sets the boundary of state. + * Exercise 1-23: Write a program to remove all comments from a C program. + * Don't forget to handle quoted strings and character constants properly. C + * comments do not nest. + * + * Answer: At first I didn't know why it was important to account for strings + * or character constants. The reason behind this is that /* and // are valid + * inside those parts of C, so they deserve special treatment. * * The states for this program are IN_MULTI for a multi-line comment, - * IN_SINGLE for a single line comment, and OUT for being outside a comment. - * These three states are all I need to determine whether I should output the - * contents of the C file or not. Characters are only output when the state is - * OUT, and there are conditions for getting into and out of comment state. + * IN_SINGLE for a single line comment, OUT for being outside a comment, and + * IN_STRING for being inside a string or character constant. These four states + * are all I need to determine whether I should output the contents of the C + * file or not. Characters are only output when the state is OUT or IN_STRING, + * and there are conditions for getting into and out of comment state. * - * I don't know of any other way to do this without invoking some higher-level - * libraries. + * This structure is known as a finite state machine (FSM). */ +#define OUT 0 #define IN_MULTI 1 #define IN_SINGLE 2 -#define OUT 0 +#define IN_STRING 3 char c, p; int status; @@ -30,7 +31,14 @@ int status; int main() { // Treat input like a stream, since that's all the K&R has explained so far. while ((c = getchar()) != EOF) { - + /* This is to account for strings and character constants */ + if (c == '\'' || c == '"') { + if (status == OUT) { + status = IN_STRING; + } else if (status == IN_STRING) { + status = OUT; + } + } // Check for the ways to open a comment, and set state accordingly if (c == '/' && status == OUT) { // Look ahead and store the character that's returned @@ -70,7 +78,7 @@ int main() { } // Output everything when we're not in a comment! - if (status == OUT) { + if (status == OUT || status == IN_STRING) { putchar(c); } -- cgit v1.2.3-54-g00ecf