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同じ loop.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を同じname []に​​ポイントしますが、name []は各ループに書き込まれるため、最後に同じ名前を5回出力します。

funcnameをarrayに変更した後、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 に答える