2

我正在编写 C 程序来查找函数并计算 C 文件中函数的行数,并将其存储到结构中。我在下面给出了我的代码。

#include <stdio.h>
#include <string.h>

#define SIZE 1024
struct fundetails
{
    int nooflines;
    char *funcname;
}s[20];
char *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] != '\0')
    {
        name[j]=dt[i];
        i++;
        j++;
    }
    name[j] ='\0';
    return name;
}

int main(int argc, char **argv)
{
    if(argc < 2)
    {
        printf("Give the filename \n");
        printf("Usage: %s filename\n", argv[0]);
        return -1;
    }
    int i, lines =0, funlines =0,count =0, fn =0, flag =0, size=0,emptyflag=0;
    char c[SIZE],b[SIZE];
    char *fname;
    FILE *fd;
    fd = fopen(argv[1],"r");
    while(fgets(c,SIZE,fd))
    {   
        emptyflag=0;
        lines++;
        size = strlen(c);
        if(size == 1 && (strcmp(c,"\n"))== 0)
            emptyflag=1;
        for(i=0;i<size;i++)
        {
            while( c[i] =='\t' || c[i] == ' ')
            {
                i++;
            }
            if( c[i] == '{')
            {
                count++;
                if(flag)
                {
                    if(!emptyflag)
                        funlines++;
                    else
                        emptyflag=0;
                }
                if(count == 1)
                {
                    fn++;
                    printf("Function %d is Started..............\n", fn); 
                    flag = 1;
                    fname=ffname(b);
                    printf("Function name is:%s\n",fname);
                }
                break;
            }
            else if( c[i] == '}')
            {
                count--;
                if(!count)
                { 
                    flag = 0;

                    printf("No of lines in the function %d is: %d\n", fn, funlines);
                    printf("Function %d is finished..........\n", fn);
                    s[fn-1].nooflines=funlines;
                    s[fn-1].funcname=fname;
                    funlines = 0;
                }
                else
                {
                    if(!emptyflag)
                        funlines++;
                    else
                        emptyflag=0;
                }
                break;
            }
            else if(flag)
            {
                if(!emptyflag)
                        funlines++;
                    else
                        emptyflag=0;
                break;
            }
        }
        strcpy(b,c);
    }
    printf("FUN_NAME\tNO_OF_LINES\n");
    for(i=0;i<fn;i++)
    {
    printf("%s\t\t%d\n",s[i].funcname,s[i].nooflines);
    }
    return 0;
}

它产生警告为try.c:26:2: warning: function returns address of local variable [enabled by default]. 它产生如下所示的输出。

Function 1 is Started..............
Function name is:fundetails

No of lines in the function 1 is: 2
Function 1 is finished..........
Function 2 is Started..............
Function name is:dhahira
No of lines in the function 2 is: 1
Function 2 is finished..........
Function 3 is Started..............
Function name is:add
No of lines in the function 3 is: 3
Function 3 is finished..........
Function 4 is Started..............
Function name is:sub
No of lines in the function 4 is: 9
Function 4 is finished..........
Function 5 is Started..............
Function name is:main
No of lines in the function 5 is: 13
Function 5 is finished..........
FUN_NAME    NO_OF_LINES
main        2
main        1
main        3
main        9
main        13

我存储function name and no of lines在同一个循环中。WQhile i1m 运行它GDB,每次

s[fn-1].nooflines=funlines;
s[fn-1].funcname=fname;

以上行,行数正确存储在结构中。但不是在函数名的情况下。 Problem:我不明白为什么它适用于线路而不适用于函数名称?是因为那个警告吗?请指导我,谢谢。

4

2 回答 2

4

在 ffname() 中,name[] 是本地的,在执行函数时会被压入堆栈。ffname()返回后,出栈,即name[]占用的内存被释放,系统可以重用内存,但在重用内存之前,数据还在。这就是为什么有时它起作用,有时不起作用。另外,这就是您收到警告的原因。

您应该在结构中将 funcname 定义为数组而不是指针。因为在funcname的时候,你总是将funcname指向same name[],而name[]是写在每个循环中,所以最后你打印了5次same name。

将 funcname 更改为数组后,应使用 strcpy 复制名称:

strcpy(funcname, name); // this is right way when funcname is array

而不是:funcname = name;

于 2012-12-21T06:47:10.450 回答
1

首先制作结构

struct fundetails
{
  int nooflines;
  char funcname[128];
}s[20];

然后修复 func ffname 的返回值:您不能返回指向将消失的数据的指针超出范围(在这种情况下,函数的结束)。作为便宜的快速改装,只需转动您的

char name[SIZE];

进入

static char name[SIZE];

然后

strcpy(s[fn-1].funcname, fname);

而不是你的

s[fn-1].funcname=fname;

输出就像

FUN_NAME        NO_OF_LINES
fundetails
                2
ffname          15
main            82

我还没有检查过你是如何识别函数的,但这似乎太天真了。(答案可能无法解决您的代码的所有问题;例如,您的代码中可能有路径在分配之前导致使用 fname?...)

于 2012-12-21T07:36:52.683 回答