Reputation: 1003
I have tried to count the number of labels present in a C program, using C itself. It works good. I extended it like, I have an array ca[]
, which contains line numbers as elements. When the corresponding lines are read, the line should not be searched for labels. The concept behind this is, I will receive an array from another program, that contains line numbers of comment lines. So, I will get the array as input, and skip processing those lines alone.
What I have tried is,
int nl=0,flag=0,i=1,j=0;
int ca[100]={3,5};
char c;
fp=fopen("chumma.c","r");
while((c=getc(fp))!=EOF)
{
if(c=='\n')
i=i+1;
if((ca[j])!=i)
{
if(c==':')
flag=1;
else if((flag==1) && (c=='\n'))
{
flag=0;nl++;
}
}
else
j++;
}
nl
is the number of labels. This doesn't check the lines itself. Kindly guide me where I have went wrong.
Upvotes: 0
Views: 161
Reputation: 1601
Try This,,
int nl=0,flag=0,i=1,j=0;
int ca[100]={3,5};
char c;
fp=fopen("Kiss.c","r");
while ((c=getc(fp))!=EOF) {
if (c == '\n') {
if (ca[j] == i) j ++;
if (flag == 1) {
flag = 0; nl ++;
}
i = i ++;
continue;
}
if (ca[j] == i)
continue;
if (c==':')
flag=1;
Upvotes: 1
Reputation: 9305
This sounds like homework/a learning exercise, so I'm going to explain the process of planning/designing a program like this. Then I'll give you a sample of one way to implement it.
One way to write these kinds of programs is by building a pair of state machines:
/*
sequence; stay in this state until */
; return to 1"
character; stay in this state until \
or "
; return to 1//
sequence; stay in this state until newline; return to 1\
extract next character, then go back to state 3Once leaving state 5:
switch
we'll go into our other state machine (below). :
then return to state 1When we see switch
, though, we need another state table because of the expression that immediately follows:
(
at start after switch
/*
and "
get treated as in state machine 1 (above))
seen{
- increment nesting level and go immediately to state 7.}
- decrement nesting level on entrance to this state; if at nesting level zero, then return to state 1 in first state machine, otherwise remain in state 7.:
;
or }
moving to states 7 and 8 respectively.Once leaving state 9:
:
then go to state 10default
then go to state 10The next step is to write a function for each state. It may be helpful to number the states and give the functions numbers. The way they operate on the "character" or "character sequence" is generally with a couple low level things I write early:
int c;
int next() { c=getchar(); return c; }
typedef int (*state)();
For example, states 2 and 3 above might be written as:
state state2() { if(c == '*' && next() == '/') return state1; return state2; }
state state3() { if(c == '"') return state1; if (c == '\\') return state7; }
It should be pretty easy to work out the rest of the states. State 5 will have a buffer that you're filling up to "read" the word:
char word[600];
int ptr;
state state5() {
ptr = 0;
while(isdigit(c) || isalpha(c)) {
word[ptr] = c;
ptr++;
if(ptr==600)abort();
next();
}
/* now leaving state 5 */
}
Once you're done with this, you can write the driver:
void statemachine1() {
state x = state1;
while(c != -1) x = x();
}
If you've made a mistake, it will be helpful to have some debugging tools. One good one is to label each state in an array:
state statelist1[] = { state1, state2, state3, state4, state5, state6, state7 };
int statenumber(state x) {
int i, n = sizeof(statelist1) / sizeof(state);
while(n-->0) if(x == statelist1[n]) return n;
abort();
}
This would be helpful when debugging; I might insert:
printf("state = %d, char = %02x (%c)\n", statenumber(x), c,c);
into the driver loop, and something like this:
printf("char = %02x (%c)\n", c,c);
in various parts as I trace the machine. This would build up a map in my mind more firmly of the state machine, and as I follow it along my test programs, it will make it easier to validate all of the states.
If things start getting difficult, I'll modify next()
to keep track of the current line:
int line = 1;
int next() { c=getchar(); if(c == '\n') line++; return c; }
that way I can use that in my printf()
statements as well.
Once I'm satisfied things are working, I'll remove the debugging code.
Good luck!
Upvotes: 2