将细节存储到C结构中

时间:2012-12-21 06:42:00

标签: c linux structure compiler-warnings

我正在编写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:我不明白为什么它在线路上工作正常,而不是为函数名称工作?是因为那个警告?请指导我,谢谢。

2 个答案:

答案 0 :(得分:4)

在ffname()中,name []是本地的,它在执行函数时被推送到堆栈。在ffname()返回之后,弹出堆栈,这意味着由name []占用的内存被释放,系统可以重用内存,但在重用内存之前,数据仍然存在。这就是为什么有时它可以工作而有时不工作的原因。此外,这就是你收到警告的原因。

您应该将struct中的funcname定义为数组而不是指针。因为当funcname,你总是将funcname指向同名[],而name []写在每个循环中,所以最后你打印相同的名字5次。

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

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

而不是:     funcname = name;

答案 1 :(得分: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的路径?...)