使用C语言计算程序中的标签数
我曾尝试使用C本身计算C程序中存在的标签数量。它工作得很好。我将其扩展为,我有一个数组使用C语言计算程序中的标签数,c,labels,C,Labels,我曾尝试使用C本身计算C程序中存在的标签数量。它工作得很好。我将其扩展为,我有一个数组ca[],其中包含行号作为元素。读取相应的行时,不应在该行中搜索标签。这背后的概念是,我将从另一个程序接收一个数组,其中包含注释行的行号。因此,我将获取数组作为输入,并跳过单独处理这些行 我试过的是 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) {
ca[]
,其中包含行号作为元素。读取相应的行时,不应在该行中搜索标签。这背后的概念是,我将从另一个程序接收一个数组,其中包含注释行的行号。因此,我将获取数组作为输入,并跳过单独处理这些行
我试过的是
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
是标签的数量。这不会检查线路本身。请告诉我哪里出了问题。这听起来像是家庭作业/学习练习,因此我将解释规划/设计这样一个程序的过程。然后我将给您一个实现它的方法的示例
编写此类程序的一种方法是构建一对状态机:
/*
序列;保持此状态直到*/
;返回到1“
字符;保持此状态直到\
或”
;返回到1/
序列;保持这种状态直到换行;返回到1\
提取下一个字符,然后返回状态3- 如果单词是
,我们将进入另一个状态机(如下)李>switch
- 如果我们没有看到
,则返回状态1:
- 否则我们的话就是一个标签;你想用它做什么就做什么,然后回到状态1
开关时,我们需要另一个状态表,因为后面紧跟着一个表达式:
初始状态/空白
从状态1开始:(
在开关之后启动
从状态1开始:所有其他字符生成一个错误
从状态2:/*
和“
被视为状态机1(如上所述)
从状态2:)
查看
从状态5:{
-增加嵌套级别并立即转到状态7
空白/状态
从状态7开始:}
-在进入该状态时降低嵌套级别;如果嵌套级别为零,则在第一个状态机中返回状态1,否则保持状态7
从状态7:已看到一个字母;保持此状态直到非字母或:
从状态7开始:如果看到任何其他情况,请保持此状态,直到分别移动到状态7和状态8为止
一旦离开第9国:
- 如果我们没有看到
:
,则转到状态10
- 否则,如果单词为默认值,则转到状态10
- 否则,这是一个标签;使用它做任何你想做的事情,然后转到状态10
下一步是为每个状态编写一个函数。对状态进行编号并给出函数编号可能会有所帮助。它们对“字符”或“字符序列”的操作方式通常与我之前编写的一些低级内容有关:
int c;
int next() { c=getchar(); return c; }
typedef int (*state)();
例如,上面的状态2和状态3可以写成:
state state2() { if(c == '*' && next() == '/') return state1; return state2; }
state state3() { if(c == '"') return state1; if (c == '\\') return state7; }
计算出其余的状态应该很容易。状态5将有一个缓冲区,您将填充该缓冲区以“读取”单词:
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 */
}
完成此操作后,可以编写驱动程序:
void statemachine1() {
state x = state1;
while(c != -1) x = x();
}
如果您犯了错误,使用一些调试工具会很有帮助。一个好的方法是标记数组中的每个状态:
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();
}
这在调试时会很有帮助;我可以插入:
printf("state = %d, char = %02x (%c)\n", statenumber(x), c,c);
进入驱动程序循环,类似这样:
printf("char = %02x (%c)\n", c,c);
在我跟踪机器的各个部分。这将在我的脑海中建立一个更牢固的状态机地图,当我沿着我的测试程序跟踪它时,它将使验证所有状态变得更容易
如果事情开始变得困难,我将修改next()
,以跟踪当前行:
int line = 1;
int next() { c=getchar(); if(c == '\n') line++; return c; }
这样,我也可以在我的printf()
语句中使用它
一旦我对工作感到满意,我将删除调试代码
祝你好运!这听起来像是家庭作业/学习练习,所以我将解释规划/设计这样一个程序的过程。然后我将给你一个实现它的方法示例
编写此类程序的一种方法是构建一对状态机:
初始状态/空白状态
从状态1开始:已看到/*
序列;保持此状态直到*/
;返回到1
从状态1开始:已看到“
字符;保持此状态,直到\
或“
;返回到1
从状态1:已看到/
序列;保持此状态直到换行;返回到1
从状态1:看到一个字母;一直保持这种状态,直到非字母和非数字
从状态1开始:如果你还看到了什么,就呆在这个状态直到换行
从状态3:看到\
提取下一个字符,然后返回状态3
一旦离开第5国:
- 如果单词是
switch
,我们将进入另一个状态机(如下)
- 如果我们没有看到
:
,则返回状态1
- 否则,我们的词就是一个标签;你想用它做什么就做什么,然后回到状态1
但是,当我们看到开关时,我们需要另一个状态表,因为后面紧跟着一个表达式:
初始状态/空白
从状态1开始:(
在开关之后启动
从状态1开始:所有其他字符生成一个错误
Fro
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;