Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9abccc4

Browse files
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

‎chapter01/1-24.c

Lines changed: 105 additions & 177 deletions
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(charline[], charsymbol[], intcharsCount[], intlen)
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)

AltStyle によって変換されたページ (->オリジナル) /