Skip to content

Commit 9abccc4

Browse files
committed
Simplify code
Simplified code by using getchar instead of getLine to extract input
1 parent 1ac60e3 commit 9abccc4

File tree

1 file changed

+105
-177
lines changed

1 file changed

+105
-177
lines changed

Diff for: chapter01/1-24.c

+105-177
Original file line numberDiff line numberDiff line change
@@ -3,210 +3,138 @@
33
* errors like unmatched parentheses, brackets and braces. Don't forget about
44
* quotes, both single and double, escape sequences, and comments. (This
55
* program is hard if you do it in full generality.)
6+
*
67
* By Faisal Saadatmand
78
*/
89

10+
11+
/* NOTE: this is not full generality solution */
12+
913
#include <stdio.h>
1014

11-
#define MAXLINE 1000
12-
#define YES 1
13-
#define NO 0
14-
#define SLASH_ASTERISK 1
15-
#define ASTERISK_SLASH 0
16-
#define IN 1
17-
#define OUT 0
15+
#define YES 1
16+
#define NO 0
17+
18+
/* globals */
19+
int leftParens = 0;
20+
int rightParens = 0;
21+
int leftBrackets = 0;
22+
int rightBrackets = 0;
23+
int leftBraces = 0;
24+
int rightBraces = 0;
1825

1926
/* functions */
20-
int getLine(char [], int);
21-
int findComment(char [], int);
22-
int delComment(char [], char [], int , int);
23-
void findCharacter(char [], char [], int [], int);
24-
void checkSyntax(char [], int [], int);
25-
26-
/* getLine function: read a line into s, return length */
27-
int getLine(char s[], int lim)
27+
void printInfo();
28+
int skipChar(int);
29+
void checkSymbolsBallance(void);
30+
void countSymbols(void);
31+
int skipComment(int);
32+
int skipQuote(int);
33+
34+
/* skipChar: skips n characters in the input stream */
35+
int skipChar(int n)
2836
{
29-
int c, i;
37+
int c;
3038

31-
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
32-
s[i] = c;
33-
34-
if (c == '\n') {
35-
s[i] = c;
36-
++i;
37-
}
39+
while (n--)
40+
c = getchar();
41+
return c ;
42+
}
3843

39-
s[i] = '\0';
44+
/* skipComment: skip characters in the input stream until encountered the
45+
* ending symbol of a c-style comment */
46+
int skipComment(int c)
47+
{
48+
int stop = NO;
4049

41-
return i;
50+
while (stop == NO && (c = getchar()) != EOF)
51+
if (c == '*' && (c = getchar()) == '/')
52+
stop = YES;
53+
return c;
4254
}
4355

44-
/* findComment function: searches line[] for the first occurrence of the first
45-
* character of a C comment notation and returns the location on finding a single
46-
* line comment or -1 on failure */
47-
int findComment(char line[], int notation)
56+
/* skipComment: skip characters in the input stream until encountered the
57+
* ending character of a c-style quote (single or double) */
58+
int skipQuote(int type)
4859
{
49-
int i, j;
50-
int quoteStart; /* location of the start of the quotation mark */
51-
int quoteEnd; /* location of the end of quotation mark */
52-
int location; /* location of C comment notation */
53-
int comment[2]; /* notation type: start or end */
54-
int lookForQuote; /* flag variable */
55-
56-
location = quoteStart = quoteEnd = -1;
57-
/* set the appropriate notation */
58-
if (notation == SLASH_ASTERISK) {
59-
comment[0] = '/';
60-
comment[1] = '*';
61-
} else if (notation == ASTERISK_SLASH) {
62-
comment[0] = '*';
63-
comment[1] = '/';
64-
}
60+
int c, stop = NO, step = 2;
6561

66-
lookForQuote = YES;
67-
/* line[x - 1] check handles escape sequences. It is unnecessary for the
68-
* start of the quote but is added for the sake of correctness. */
69-
for (i = 0; line[i] != '\0'; ++i) {
70-
if (line[i] == comment[0] && line[i + 1] == comment[1]) {
71-
if (notation == ASTERISK_SLASH)
72-
location = i + 1; /* end of comment including notation */
73-
else
74-
location = i; /* start of comment including notation */
75-
}
76-
if (line[i] == '\"' && line[i - 1] != '\\' && lookForQuote == YES) {
77-
quoteStart = i;
78-
for (j = i + 1; line[j] != '\0'; ++j)
79-
if (line[j] == '\"' && line[j - 1] != '\\')
80-
quoteEnd = j;
81-
lookForQuote = NO;
82-
}
62+
while (stop == NO && (c = getchar()) != EOF) {
63+
if (c == '\\')
64+
c = skipChar(step);
65+
if (c == type)
66+
stop = YES;
8367
}
84-
85-
/* check if notation is inside a double quotation marks */
86-
if (location >= 0 && quoteStart >= 0)
87-
if (location > quoteStart && location < quoteEnd)
88-
location = -1; /* not a C comment */
89-
90-
/* check if notation is inside a multi-line double quotation marks */
91-
if (location >= 0 && quoteStart >= 0 && quoteEnd < 0)
92-
// if (location < quoteStart)
93-
location = -1; /* not a C comment */
94-
95-
return location;
68+
return c;
9669
}
9770

98-
/* delComment function: deletes C comments from line string stores result in
99-
* modLine */
100-
int delComment(char line[], char modLine[], int start, int end)
101-
{
102-
int i, j;
103-
int status;
104-
105-
i = j = 0;
106-
107-
/* no notation - delete entire line */
108-
if (start < 0 && end < 0)
109-
for (i = 0; line[i] != '\0'; ++i)
110-
modLine[i] = '\0';
111-
/* start but no end - delete rest of line */
112-
else if (start >= 0 && end < 0)
113-
for (i = 0; i < start; ++i)
114-
modLine[i] = line[i];
115-
/* end but no start - move text after comment to the beginning of line */
116-
else if (start < 0 && end >= 0)
117-
for (j = end + 1; line[j] != '\0'; ++j) {
118-
modLine[i] = line[j];
119-
++i;
120-
}
121-
/* full comment embedded - move text after comment to start location */
122-
else if (start >= 0 && end >= 0) {
123-
for (i = 0; i < start; ++i)
124-
modLine[i] = line[i];
125-
for (j = end + 1; line[j] != '\0'; ++j) {
126-
modLine[i] = line[j];
127-
++i;
128-
}
71+
/* countSymbols: count c-style demarcating symbols for comments and quote */
72+
void countSymbols(void) {
73+
extern int leftParens, rightParens, leftBrackets, rightBrackets,
74+
leftBraces, rightBraces;
75+
int c;
76+
77+
while ((c = getchar()) != EOF) {
78+
if (c == '/' && (c = getchar()) == '*') /* skip comments */
79+
c = skipComment(c);
80+
if (c == '"') /* skip double quotes */
81+
c = skipQuote(c);
82+
if (c == '\'') /* slip single quotes */
83+
c = skipQuote(c);
84+
if (c == '(')
85+
++leftParens;
86+
if (c == ')')
87+
++rightParens;
88+
if (c == '[')
89+
++leftBrackets;
90+
if (c == ']')
91+
++rightBrackets;
92+
if (c == '{')
93+
++leftBraces;
94+
if (c == '}')
95+
++rightBraces;
12996
}
130-
131-
/* end of line formatting */
132-
if (start < 0 && end < 0)
133-
modLine[0] = '\n';
134-
else if (start >= 0 && end < 0) {
135-
modLine[i] = '\n';
136-
modLine[i + 1] = '\0';
137-
} else
138-
modLine[i] = '\0';
139-
140-
/* status of the current deleted comment: single or multi-line */
141-
status = 0;
142-
if ((start >= 0 && end < 0) || (start < 0 && end < 0))
143-
status = 1;
144-
else if (start < 0 && end >= 0)
145-
status = 0;
146-
147-
return status;
14897
}
14998

150-
/* findCharcter function: counts the occurrence of a characters from symbol in
151-
* line and stores results in charsCount. len is the length of symbol array */
152-
void findCharacter(char line[], char symbol[], int charsCount[], int len)
99+
/* checkSymbolsBallance: check if number of c-style demarcating symbols for
100+
* comments and quotes are balanced. Print an error message if not. */
101+
void checkSymbolsBallance(void)
153102
{
154-
int i, j;
155-
static int quoteState; /* double quote state flag */
156-
157-
quoteState = OUT;
158-
for (i = 0; i <= len ; ++i)
159-
/* line[x - 1] check handles escape sequences. */
160-
for (j = 0; line[j] != '\0'; ++j)
161-
if (quoteState == OUT && line[j] == '\"' && line[j - 1] != '\\')
162-
quoteState = IN;
163-
else if (quoteState == IN && line[j] == '\"' && line[j - 1] != '\\')
164-
quoteState = OUT;
165-
else if (line[j] == symbol[i] && line[j + 1] != '\'' && quoteState
166-
== OUT)
167-
++charsCount[i];
103+
extern int leftParens, rightParens, leftBrackets, rightBrackets,
104+
leftBraces, rightBraces;
105+
106+
if (leftParens - rightParens < 0)
107+
printf("Error: missing '('\n");
108+
else if (leftParens - rightParens > 0)
109+
printf("Error: missing ')'\n");
110+
if (leftBrackets - rightBrackets < 0)
111+
printf("Error: missing '['\n");
112+
else if (leftBrackets - rightBrackets > 0)
113+
printf("Error: missing ']'\n");
114+
if (leftBraces - rightBraces < 0)
115+
printf("Error missing '{'\n");
116+
else if (leftBraces - rightBraces > 0)
117+
printf("Error missing '}'\n");
168118
}
169119

170-
void checkSyntax(char symbol[], int charsCount[], int len)
120+
/* printInfo: print the number of demarcating symbols for comments and quotes */
121+
void printInfo(void)
171122
{
172-
int i, syntaxError = 0;
173-
174-
for (i = 0; i <= len; i += 2)
175-
if (charsCount[i] != charsCount[i + 1]) {
176-
printf("Syntax ERROR: unbalanced number of %c %c\n",
177-
symbol[i], symbol[i + 1]);
178-
syntaxError = 1;
179-
}
180-
if (syntaxError != 1)
181-
printf("Syntax check: no errors found\n");
123+
extern int leftParens, rightParens, leftBrackets, rightBrackets,
124+
leftBraces, rightBraces;
125+
126+
printf("'(': %i ')': %i Total: %i\n",
127+
leftParens, rightParens, leftParens + rightParens);
128+
printf("'[': %i ']': %i Total: %i\n",
129+
leftBrackets, rightBrackets, leftBrackets + rightBrackets);
130+
printf("'{': %i '}': %i Total: %i\n",
131+
leftBraces, rightBraces, leftBraces + rightBraces);
182132
}
133+
183134
int main(void)
184135
{
185-
int len; /* current line length */
186-
int start; /* comment's beginning */
187-
int end; /* comment's end */
188-
int status; /* multi-line comments flag */
189-
char line[MAXLINE]; /* current input line */
190-
char modLine[MAXLINE]; /* modified output line */
191-
int charsCount[6];
192-
char symbol[6] = { '{', '}', '(', ')', '[', ']' };
193-
194-
for (len = 0; len <= 6 ; ++len) /* use len temporarily as an index */
195-
charsCount[len] = 0;
196-
197-
status = 0;
198-
while ((len = getLine(line, MAXLINE)) > 0) {
199-
200-
start = findComment(line, SLASH_ASTERISK);
201-
end = findComment(line, ASTERISK_SLASH);
202-
203-
if (start < 0 && end < 0 && status == 0) /* no comment found */
204-
findCharacter(line, symbol, charsCount, 5);
205-
else {
206-
status = delComment(line, modLine, start, end);
207-
findCharacter(modLine, symbol, charsCount, 5);
208-
}
209-
}
210-
checkSyntax(symbol, charsCount, 5);
136+
countSymbols();
137+
printInfo();
138+
checkSymbolsBallance();
211139
return 0;
212140
}

0 commit comments

Comments
 (0)