Thread: search a date

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    17

    search a date

    Hello,

    I want to make a function (int search_date(FILE *fp,time_t time) that searches a date in a log file and makes the file pointer fp point to this date (if the date doesn't exist, point to the date immediately after the searched date ; if more than one date exists, point to the lattest one).
    In my log, every line begins with a date, of the form "Dec 14 00:00:00".
    Here is my program :

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
     
    time_t string_to_time_t(char *s)
    {
            time_t rawtime;
            struct tm * timeinfo;
            char month_s[4] ;
            int month,day,hour,minute,second;
            sscanf(s, "%3s %d %d:%d:%d", month_s, &day, &hour, &minute, &second);
     
            char * month_names[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
            int i=0;
            while( strcmp(month_s,month_names[i]) != 0  )
                    i++;
            month=i;
     
            time (&rawtime);
            timeinfo=localtime(&rawtime);
            timeinfo->tm_mon=month;
            timeinfo->tm_mday=day;
            timeinfo->tm_hour=hour;
            timeinfo->tm_min=minute;
            timeinfo->tm_sec=second;
            return mktime(timeinfo);
    }
     
    time_t get_date(FILE *fp)
    {
            char s[16];
            return string_to_time_t(fgets(s,16,fp));
    }
     
    int goto_nextline(FILE *fp)
    {
            int c; //EOF is a int
            do c=fgetc(fp) ;
            while ((c != '\n') &&  (c !=EOF));
            if (c=='\n')
                    return 0;
            else
                    return 1;
    }
     
     
    void goto_beginning_of_line(FILE *fp)
    {
            int c;
            if (ftell(fp) !=0)
            {
                    fseek(fp,1,SEEK_CUR);
                    do
                    {
                            fseek(fp,-2,SEEK_CUR);
                            c=fgetc(fp);
                    }
                    while ( ftell(fp)-2>=0 && c != '\n' );
                    if( ftell(fp)==1 )
                            fseek(fp,-1,SEEK_CUR);
            }
    }
     
    int search_date(FILE *fp, time_t time)
    {
            FILE *fpmin, *fpmax, *fptmp;
            time_t timemin, timemax;
            fpos_t pos;
            fpmin=fpmax=fptmp=fp;
            fseek(fpmin,0,SEEK_SET);
            fseek(fpmax,0,SEEK_END);
            fseek(fptmp,0,SEEK_SET);
            timemin=get_date(fpmin);
            goto_beginning_of_line(fpmax);
            timemax=get_date(fpmax);
            fgetpos(fpmin,&pos);
            while(goto_nextline(fpmin)==0 && get_date(fpmin)<time)
            {
                    fsetpos(fpmin,&pos);
                    fsetpos(fptmp,&pos);
                    float weight=(float)(time-timemin)/(float)(timemax-timemin);
                    long difference=ftell(fpmax)-ftell(fpmin);
                    fseek(fptmp,(long) weight * difference,SEEK_CUR);
                    goto_beginning_of_line(fptmp);
                    if (time < get_date(fptmp))
                    {
                            fpmax=fptmp;
                            timemax=get_date(fpmax);
                    }
                    else
                    {
                            fpmin=fptmp;
                            timemin=get_date(fpmin);
                            fgetpos(fpmin,&pos);
                    }
            }
            fp=fpmin;
            return 0;
    }
     
    int main(int argc, char **argv)
    {
            FILE *fp=fopen("log.txt","r");
            if (fp==NULL)
                    fprintf(stderr,"File can't be opened\n");
            else
            {
                    time_t time=string_to_time_t("Dec 11 12:00:00");
                    search_date(fp,time);
                    //do some things here
            }
            fclose(fp);
            return 0;
    }
    This program doesn't work (segmentation fault).
    Can you help me to make it work please?

    Regards.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ericad View Post
    This program doesn't work (segmentation fault).
    Can you help me to make it work please?
    You need to locate the fault.

    gcc -g myprog.c
    gdb ./a.out

    when the prompt appears type "run". This will tell you which line is causing the fault.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    17
    It says ./a.out : no such file or directory.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ericad View Post
    It says ./a.out : no such file or directory.
    "myprog.c" here would be the name of your source file. If gcc compiled your code (ie, it did not stop because of an explicit "error") then by default it names the executable a.out.

    So either:
    1) gcc did not compile your program
    2) you are in the wrong directory suddenly
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    17
    Ok it works now.
    The answer is :
    program received signal SIGSEGV, Segmentation fault.
    0x0020c9ba in strcmp() from /lib/tls/i686/cmov/libc.so.6

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ericad View Post
    Ok it works now.
    The answer is :
    program received signal SIGSEGV, Segmentation fault.
    0x0020c9ba in strcmp() from /lib/tls/i686/cmov/libc.so.6
    Well, that's lucky, there's only one strcmp() in your program.

    Code:
    while( strcmp(month_s,month_names[i]) != 0  )
    I would guess you are running off the end of month_names. Run it in gdb again, when it segfaults, type

    print i

    If i is 12 or more, then that is the problem.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Dec 2009
    Posts
    17
    the answer is No symbol i in current context

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ericad View Post
    the answer is No symbol i in current context
    Yeah, the debugger has some limitations.

    Add this inside your while loop:
    Code:
    while( strcmp(month_s,month_names[i]) != 0  )
    printf("i=%d\n",i); fflush(stdout);
                    i++;
    You need to find out which iteration of the while loop is causing the seg fault in strcmp(). Now just compile and run it regularly. If it is less than 12, try adding a couple of %s into the printf to show the value of month_s and mouth_names[i].
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Dec 2009
    Posts
    17
    Well anyway it sounds clear to me why the strcmp is wrong : that's because the file pointer doesn't point to the beginning of a date (such as "Dec 12 00;00:00").
    That's because there are some errors in search_date.
    Can you help me to spot them and correct them please?

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ericad View Post
    that's because the file pointer doesn't point to the beginning of a date
    That's because there are some errors in search_date.
    So what does the file pointer point to? It is more difficult to spot errors just by looking at code than it is to find errors by executing the code and examining what it does.

    To do that, you need to add in some appropriate printf() lines in places where you want to double check, eg, whether a file pointer is in the place you want it to be, etc. Always follow a printf() debugging line with fflush(stdout) to insure the data is not held in a console buffer.

    You can also do this in gdb. Compile -g and start the executable in gdb, but before you type run, type
    break ##

    where ## is a line number in the code, for example, somewhere in search_date(). Execution will pause at that point and you should be able to examine the value of variables using "print", eg.
    print fp
    You can then type "cont" and it will keep going -- if the function is called more than once or the breakpoint is in a loop, you will hit it again.

    It appears you have written a lot of code without doing any verification to see if it does what you want, and now you are stuck guessing what the error is. Sometimes unavoidable but generally a Very Bad Habit!
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Checking array for string
    By Ayreon in forum C Programming
    Replies: 87
    Last Post: 03-09-2009, 03:25 PM
  2. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM