关闭文件时出现分段错误错误

时间:2014-10-22 02:11:50

标签: c file pointers fault

所有

我有一段可怕的时间试图弄清楚为什么我一直会遇到这些分段错误。我试图在服务器上打开一个文件,从中读取,关闭它。在我尝试关闭文件之前,一切似乎都进展顺利。这些子程序一次从同一程序调用一个。当每月下雨时,它会使用下面的代码为指针打印出值22。每天下雨时,指针值打印为(null)。如果取消注释fclose,程序将停止工作并在达到fclose行时显示分段错误。我在两个例程中打开相同的文件。主要是每天下雨前每月下雨。请询问您是否需要更多信息,非常感谢任何帮助!!

例程如下:

float monthly_rain(int year, int month)
{   
    float mon_rain=0, mrain, rain1, rain2, d, cur_hour=0, day;
    char filename[size];
    FILE *afile;

    //calculates monthly rainfail
    for(d=1;d<day;d++)
    {
        sprintf(filename, "%s%4d%02d%02d.dat",ARCHIVEDIR,year,month);   //step through the days of the month(d not mday)
        printf("\nFilename is = %s\n", filename);
        if((afile=fopen(filename, "r"))!= NULL)
        {
            if(d==1)    //Get first reading of the month - total rain is 9th column 
                mrain = fscanf( afile, "%*d:%*d%*d%*d%*d%*d%*d%*d%*d%d%*d%*d%*d%*d%*d", &rain1); 
            else    //scan till you reach the last day of the month
            {   //Step through the columns, exit when last day reached
                cur_hour=0;     //resets current hour counter for each new day
                while ((mrain = fscanf( afile, "%*d:%*d%*d%*d%*d%*d%*d%*d%*d%d%*d%*d%*d%*d%*d%*c", &rain2))!= -1)   
                    cur_hour++;     //probable wont need this till daily calculation, unless we really want it in monthly too.
            }
        }
    }
    mon_rain=(rain2*.01)-(rain1*.01);   //Save the monthly reading
    printf("\nMon rain as in func. %.2f\n", mon_rain);
    printf("\npointer = %d\n", afile);  
    //fclose(afile);
    printf("\n\nflag 1\n\n");
    return mon_rain;
}//end monthly rainfall calc.

float daily_rain(int year, int month, int day)
{
    float daily_rain=0, mrain, rain1, rain2, cur_hour=0;
    char filename[size];
    FILE *afile;

    //daily rainfall calc.
    sprintf(filename, "%s%4d%02d%02d.dat",ARCHIVEDIR, year, month, day);    //get the current days archive file
    printf("\nFilename is = %s\n", filename);
    if((afile=fopen(filename, "r"))!= NULL)     //open the file
    {
        //Step through the columns, exit when last day reached
        while ((mrain = fscanf( afile, "%*d:%*d%*d%*d%*d%*d%*d%*d%*d%d%*d%*d%*d%*d%*d%*c", &rain2))!= -1)
        {
            if(cur_hour==0)
                rain1=rain2;                //save the first reading of the day
            cur_hour++;
        }
    }
    daily_rain=(rain2*.01)-(rain1*.01);     //the daily rainfall saved here
    printf("\nDaily rain as in func. %.2f\n", daily_rain);
    printf("\npointer = %s\n", afile);
    //fclose(afile);
    return daily_rain;
}//end daily rainfall calc. 

一些有助于澄清一些问题的补充......

%* d占位符用于忽略下一个整数。我正在阅读15列数据文件中的第9列。到目前为止,我没有遇到任何问题。大小也定义为100.

再次感谢。

1 个答案:

答案 0 :(得分:1)

这里有很多问题。

如果您成功fclose(),则应该只尝试fopen()个文件。改为:

    if((afile=fopen(filename, "r"))!= NULL)
    {
        if(d==1)
            mrain = fscanf( afile, "%*d:%*d%*d%*d%*d%*d%*d%*d%*d%d%*d%*d%*d%*d%*d", &rain1); 
        else 
        { 
            cur_hour=0; 
            while ((mrain = fscanf( afile, "%*d:%*d%*d%*d%*d%*d%*d%*d%*d%d%*d%*d%*d%*d%*d%*c", &rain2))!= -1)   
                cur_hour++;
        }

        fclose(afile);  /*  <---- close it here, not at the end  */
    }

目前,在所有情况下,您的代码可能希望做的最好的事情是关闭您打开的最后一个文件。如果您设置afile的最后一件事是NULL,那么您将崩溃。

此外,如果您的fopen()调用失败,则不要继续使用其余的逻辑。

例如,daily_rain=(rain2*.01)-(rain1*.01);daily_rain()中的朋友即使您的文件未打开且rain1rain2未初始化也会运行,这很糟糕。将这些内容也移动到if块中,这样它只会在成功打开文件的情况下运行。

您的循环也无法解释fscanf()可以返回EOF这一事实。现在你似乎想在fscanf()返回0时终止,但如果它返回EOF,你就会坚持到底。

另外,当你这样称呼时:

for(d=1;d<day;d++)

day未初始化,因此此循环很可能会持续很长时间。