2012-12-21 49 views
2

我正在编写C程序来查找函数并计算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在相同loop.WQhile i1m在GDB运行它,的

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

上述行每次,线的数目中的结构存储correctly.But不在 函数名的情况下。 Problem:我不明白,为什么它正常工作的线和不工作的函数名?是因为那个警告吗?请指导我,谢谢。

回答

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 

我还没有检查如何识别功能,但它似乎太多天真。 (答案可能不能解决你的代码的所有问题;例如,在代码被分配之前可能存在路径)...

4

在ffname()中,名称[]是本地的,执行该函数时将其推送到堆栈。 ffname()返回后,堆栈弹出,这意味着名称[]占用的内存被释放,系统可以重新使用内存,但在内存被重用之前,数据仍然存在。这就是为什么有时它有效,有时不适用。另外,这就是为什么你会收到警告。

您应该在结构中将funcname定义为数组而不是指针。因为当funcname时,你总是将funcname指向相同的名字[],而名称[]写在每个循环中,这样最后你打印出相同的名字5次。

更改后funcname的数组,你应该使用的strcpy复制名称:

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

不是: funcname的=名称;

+0

如果我将name []声明为全局的,将先生,它解决了这个问题? – Dhasneem

+0

如果您将名称[]定义为全局名称,则会在您的progream的生命周期中抓取内存。它会解决问题。但这不是最好的解决方案。更好的方法是将一个缓冲区传递给ffname()。 – TieDad

+0

谢谢你,先生,这有助于克服警告。但输出保持不变。 – Dhasneem