我想编写一个C代码以查找C文件中的所有函数并打印相应的函数名称。
我的代码是:
#include <stdio.h>
#include <string.h>
#define SIZE 1024
void ffname(char *line)
{
int i=1,j=0;
char *dt;
char *name;
strtok(line,"(");
dt = strchr(line,' ');
if(dt[i] == '*')
i++;
while(dt[i] != ' ')
{
name[j]=dt[i];
i++;
j++;
}
name[j] =' ';
printf("Function name is: %sn", name);
}
int main(int argc, char **argv)
{
if(argc < 2)
{
printf("Give the filename n");
printf("Usage: %s filenamen", argv[0]);
return -1;
}
int i, lines =0, funlines =0,count =0, fn =0, flag =0;
char c[100],b[100];
FILE *fd;
fd = fopen(argv[1],"r");
while(fgets(c,SIZE,fd))
{
lines++;
i=0;
for(i=0;i<strlen(c);i++)
{
while( c[i] =='t' || c[i] == ' ')
{
i++;
}
if( c[i] == '{')
{
count++;
if(flag)
{
funlines++;
}
if(count == 1)
{
fn++;
printf("Function %d is Started..............n", fn);
flag = 1;
ffname(b);
}
break;
}
else if( c[i] == '}')
{
count--;
if(!count)
{
flag = 0;
printf("No of lines in the function %d is: %dn", fn, funlines);
printf("Function %d is finished..........n", fn);
funlines = 0;
}
else
{
funlines++;
}
break;
}
else if(flag)
{
funlines++;
break;
}
}
strcpy(b,c);
}
printf("Total no of fucnion%dn",fn);
printf("Total no of lines%dn",lines);
return 0;
}
当我将以下C文件作为输入时,
#include<stdio.h>
void add()
{
int a=5,b=7;
printf("Addition is:%dn", a+b);
}
void sub()
{
int a=20,b=8;
printf("Subtraction is:%dn", a-b);
}
void main()
{
char *name="dhahira dhasneem";
char *line;
line=strchr(name,' ');
printf("Line:%sn",line);
printf("Name:%sn",name);
add();
sub();
}
我得到以下输出。
Function 1 is Started..............
Segmentation fault (core dumped)
我使用valgrind
,但我不知道如何识别错误。请引导我。谢谢。
更新:
当我使用建议的答案时,我得到了输出。之后,我想将以前的代码扩展为将功能(功能名称和功能深度)的详细信息存储到结构中。当我用来存储简单程序的功能详细信息时,我正在获得输出。但是我在程序中收到以下输出,当我在 gdb
中运行。
(gdb) b 87
Breakpoint 1 at 0x804885e: file fun_printstruct.c, line 87.
(gdb) r dat.c
Starting program: /home/dhahira/dhas/Project/a.out dat.c
Function 1 is Started..............
Program received signal SIGSEGV, Segmentation fault.
0x080485d4 in ffname (line=0xbfffe71c "/*struct *dhahira", name=0x0)
at fun_printstruct.c:21
21 name[j]=dt[i];
(gdb) s
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
我的代码是:(扩展以将功能详细信息存储到结构中)
#include <stdio.h>
#include <string.h>
#define SIZE 1024
void ffname(char *line)
{
int i=1,j=0;
char *dt;
char name[SIZE];
strtok(line,"(");
dt = strchr(line,' ');
if(dt[i] == '*')
i++;
while(dt[i] != ' ')
{
name[j]=dt[i];
i++;
j++;
}
name[j] =' ';
printf("Function name is: %sn", name);
}
int main(int argc, char **argv)
{
if(argc < 2)
{
printf("Give the filename n");
printf("Usage: %s filenamen", argv[0]);
return -1;
}
int i, lines =0, funlines =0,count =0, fn =0, flag =0, fg=0,size=0,emptyflag=0,commandflag=0;
char c[SIZE],b[SIZE],st[SIZE],d[SIZE];
int command[]={};
FILE *fd;
fd = fopen(argv[1],"r");
while(fgets(c,SIZE,fd))
{
emptyflag=0;
lines++;
for(i=0;i<(sizeof(command)/4);i++)
{
if(lines == command[i])
{
commandflag=1;
break;
}
}
strcpy(st,c);
strtok(st," ");
size = strlen(c);
if(size == 1 && (strcmp(c,"n"))== 0)
emptyflag=1;
if( !strcmp(st,"struct"))
fg=1;
for(i=0;i<size;i++)
{
if(commandflag)
{
break;
}
while( c[i] =='t' || c[i] == ' ')
{
i++;
}
if( c[i] == '{')
{
count++;
if(flag)
{
if(!emptyflag)
funlines++;
else
emptyflag=0;
}
if(count ==1 && fg ==1)
{
if(b[strlen(b)-2] == ')')
{
fn++;
printf("Function %d is Started..............n", fn);
flag = 1;
ffname(b);
}
else
{
count--;
}
}
else if(count == 1)
{
fn++;
printf("Function %d is Started..............n", fn);
flag = 1;
ffname(b);
}
break;
}
else if( c[i] == '}')
{
count--;
if(count ==0 && fg ==1)
{
flag = 0;
printf("No of lines in the function %d is: %dn", fn, funlines);
printf("Function %d is finished..........n", fn);
funlines = 0;
fg=0;
}
else if(count ==0)
{
flag = 0;
printf("No of lines in the function %d is: %dn", fn, funlines);
printf("Function %d is finished..........n", fn);
funlines = 0;
}
else if(count == -1)
{
count=0;
fg=0;
}
else
{
if(!emptyflag)
funlines++;
else
emptyflag=0;
}
break;
}
else if(flag ==1 && fg==1)
{
if(!emptyflag)
funlines++;
else
emptyflag=0;
break;
}
else if(flag)
{
if(!emptyflag)
funlines++;
else
emptyflag=0;
break;
}
break;
}
if(commandflag == 1)
commandflag = 0;
else
strcpy(b,c);
}
printf("Total no of fucnion%dn",fn);
printf("Total no of lines%dn",lines);
return 0;
}
请指导我克服这个问题。
由于扩展了代码,这个问题是否来了?(我可以分开获得正确的输出。)
您将SIZE
声明为1024,然后读取为长度100:
#define SIZE 1024
// ... snip ....
char c[100],b[100];
FILE *fd;
fd = fopen(argv[1],"r");
while(fgets(c,SIZE,fd))
这意味着您在数组的界限,堆栈的其余部分中写得很好,并导致腐败。在这种情况下,这可能实际上并没有发生,因为您的输入文件中的行均不到100个字符,但是如果有人通过长行中的文件传递。
这应该是
char c[SIZE],b[SIZE];
或在fgets()
中使用sizof()
:
fgets(c,sizeof(c),fd)
正如其他人指出的那样,最好打开所有可用警告;这将帮助您更快地捕获错误。在GCC或Clang中,我建议-Wall -Wextra -Werror
;这将使所有常见的警告能够将警告视为错误,因此您不能忽略它们。如果我在您的代码上运行它,我也会收到以下警告:
sf.c:16:9: error: variable 'name' is uninitialized when used here
[-Werror,-Wuninitialized]
name[j]=dt[i];
^~~~
sf.c:9:15: note: initialize the variable 'name' to silence this warning
char *name;
^
= NULL
sf.c:40:18: error: comparison of integers of different signs: 'int' and 'size_t'
(aka 'unsigned long') [-Werror,-Wsign-compare]
for(i=0;i<strlen(c);i++)
~^~~~~~~~~~
第二个不是一个严重的问题,只需将其施放或声明i
未签名;您应该第一个修复。您需要在堆栈(char name[SIZE];
或类似)或动态(char *name = malloc(strlen(line));
或类似的东西)上分配一个名称的缓冲区。实际上,name
是一个非初始化的指针。它可以指向内存中的任何位置,一旦您尝试通过在name[j]
中存储某些内容来将其删除,您就会写入无效的内存区域并获得segfault。
最后,一旦解决了这些问题,如果您遇到了其他问题,我建议在调试器下运行它,并查看问题发生在哪里。如果您使用的是IDE,它可能内置了一个调试器接口;如果不是,则使用-g
编译,然后运行gdb executable arguments
。