Thread: Scaninng from string

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    10

    Scaninng from string

    i have the following function

    Code:
    void fixdate(char *pt, int* d, int* m, int* y, int* h, int* min, int* pa)
    {
        char month[3];
        
        sscanf(pt, "%*s %d %s %d %d %d", d, month, y, h, min);
    
    
        if(*h>12)
        {
            *h = *h - 12;
            *pa = 2;
        }
        else
        {
            *pa = 1;
        }
    
    
        if(strcmp(month,"Jan") == 0)
        {
            *m = 1;
        }
        if(strcmp(month,"Feb") == 0)
        {
            *m = 2;
        }
        if(strcmp(month,"Mar") == 0)
        {
            *m = 3;
        }
        if(strcmp(month,"Apr") == 0)
        {
            *m = 4;
        }
        if(strcmp(month,"May") == 0)
        {
            *m = 5;
        }
        if(strcmp(month,"Jun") == 0)
        {
            *m = 6;
        }
        if(strcmp(month,"Jul") == 0)
        {
            *m = 7;
        }
        if(strcmp(month,"Aug") == 0)
        {
            *m = 8;
        }
        if(strcmp(month,"Sep") == 0)
        {
            *m = 9;
        }
        if(strcmp(month,"Oct") == 0)
        {
            *m = 10;
        }
        if(strcmp(month,"Nov") == 0)
        {
            *m = 11;
        }
        if(strcmp(month,"Dec") == 0)
        {
            *m = 12;
        }
    }
    i try to scan string with the following format sample

    Date: 25 Sep 2002 14:52:31

    when i check the values, the minute int equals 0. How can i properly scan the string taking in account the format of the string?

    i'm using sscanf(pt, "%*s %d %s %d %d %d", d, month, y, h, min);
    what should i change?
    Last edited by Donald Salguero; 10-24-2012 at 05:58 PM.

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    You're using an asterisk in the first format specifier to ignore the first string. Between 'h' and 'min', are there any special things you wish to ignore?

  3. #3
    Registered User
    Join Date
    Mar 2012
    Posts
    10
    the complete string that i scan has the following format:
    "Date: dd month yyyy hh:mm:ss"

    the time is formatted as

    hh:mm:ss

    i want the hour int (*h) to be hh, and the minute int (*m) to be mm. I'm trying to ignore the colon in between hh and mm

    i'm using %*s to ignore "Date:" that is always at the begging of each string

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    You're using "%*s" to ignore a string. So what might you put to ignore a single character (such as ':')? And where?

  5. #5
    Registered User
    Join Date
    Mar 2012
    Posts
    10
    i tried using
    sscanf(pt, "%*s %d %s %d %d %*[^:]c %d", d, month, y, h, min);
    sscanf(pt, "%*s %d %s %d %d %[^:]c %d", d, month, y, h, min);

    but the minute int always ended up as 0 even though the string shows different

  6. #6
    Registered User
    Join Date
    Oct 2012
    Posts
    99
    Does it scan in the int variable "hours" correctly? Are you able to avoid scanning in the colons between the hours/minutes?

  7. #7
    Registered User
    Join Date
    Mar 2012
    Posts
    10
    The only variable that causes me problems is the minute int. The hours are as they should be, and i can do the proper operations with them.

    If i had to guess is that after scanning the hours and while scanning the first colon the scan fails and stops, giving a null pointer to the minute pointer which would explain (i guess) why i get a 0 int when printing it.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I just ignore the g char.

    Code:
    #include <stdio.h>
    
    int main(void) {
       char s[]= {"Date: 25 Sep 2002 14:52:31"};
       char g;
       char month[4];
       int date,year,hour,minute,second;
       
       sscanf(s, "%*s %d %s %d %d%c%d%c%d",&date,month,&year,&hour,&g,&minute,&g,&second);
    
       printf("%d %s %d %d:%d:%d\n",date,month,year,hour,minute,second);
    
       printf("\n");
       return 0;
    }

  9. #9
    Registered User
    Join Date
    Mar 2012
    Posts
    10
    thank you very much Adak, it worked as it should.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Service with a smile, mate.

  11. #11
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    If you need a specific character, just stick it into the scan pattern.

    Quote Originally Posted by Donald Salguero View Post
    i tried using
    sscanf(pt, "%*s %d %s %d %d %*[^:]c %d", d, month, y, h, min);
    That does not work, because the [ is the conversion specifier for character lists. "%*[^:]c" actually means "Skip (without storing) any number of non-colon characters. Then require a lowercase c in the input."

    The way I'd do this is
    Code:
    sscanf(pt, "%*s %d %3s %d %d:%d", d, month, y, h, min);
    which will return 5 if it successfully converted all five stored fields. (Skipped fields and pattern characters are not counted.) Also, it will simply return 2 instead of overflowing your month buffer if the date happens to be say "25 January 2012 23:59".

    Buffer overruns are bad, mmkay?

    Actually, you could make your month buffer longer (say nice round 16 characters total; using %15s in the pattern above), then simply do month[3] = '\0'; before the comparisons. That way you'd support both abbreviations and full month names.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 22
    Last Post: 07-28-2011, 01:26 PM
  2. Replies: 7
    Last Post: 06-16-2011, 06:21 PM
  3. Replies: 5
    Last Post: 05-09-2010, 10:58 AM
  4. Replies: 1
    Last Post: 10-31-2005, 11:36 AM
  5. Replies: 7
    Last Post: 07-18-2005, 08:43 AM