sscanf() a phone number as a long int

09 Oct 2012

Hello,

I'm wondering if any one can help me retrieve a mobile phone number using sccanf()? (or any other method!)

So far I have used both sscanf(); and strncmp(); successfully in different routines throughout my program, however I'm stuck trying to extract a phone number!

The string held in the char buffer... (note: 2x digits in the number have been altered for privacy reasons)

$$+CMGR: "REC UNREAD","+61435464839","","12/10/08,20:33:34+44"$$TEST MESSAGE$$$$OK$$

The code I'm using to extract the phone number...

   if (strncmp(GPRSbuffer, "$$+CMGR",7) == 0) {
        if (sscanf(GPRSbuffer, "$$+CMGR: \"REC UNREAD\",\"+%ld\",\"\",\"", &number)>0){
        pc.printf("made it");
        pc.printf("\n\n%ld", number);
        }
   }

It does make it through the sccanf if statement (confirmed by the printf 'made it'), however the number (long int) returned by sscanf is

1305862685

does anyone know what I'm doing wrong?? I've tried %lu %ld data types .. and I have confirmed that the data types are declared appropriately.

(forgive me if this is a newbie question, I'm merely a hobbyist with computer science and i've spent all of my research energy on this one so far)

Regards

- Sam

09 Oct 2012

Hi Sam,

61,435,464,839 is a larger number than can be stored in 31 bits (1 of the 32 bits is for the sign).

2,147,483,648 is the maximum in 31 bits.

61435464839 / 2147483648 = 28 remainder 1305922695.

The number you are seeing is the remainder. You might be better off storing phone numbers as strings, this would also allow you to store the "+" and would mean that if your data ever includes a number with a leading zero it won't be stripped.

If for some reason you're required to store the number in a numeric type you could split it into two numbers.

#include "mbed.h"

Serial pc(USBTX, USBRX);

int main() {
    long country_code, number;

    if (sscanf("$$+CMGR: \"REC UNREAD\",\"+61435464839\",\"\",\"12/10/08,20:33:34+44\"$$TEST MESSAGE$$$$OK$$", 
               "$$+CMGR: \"REC UNREAD\",\"+%2ld%9ld\",\"\",\"", &country_code, &number) > 0) {
        pc.printf("%ld%ld\r\n", country_code, number);
    }
}

Steve

09 Oct 2012

Hi Steve,

Thanks for the detailed reply, it all makes sense now! I've managed to get it working using your first suggestion, just after posting my query I realised that the size of the "sms header" is constant so I decided to simply copy the individual bytes using...

for(int  k = 24; k < 35; k ++){
      number[k-24] = GPRSbuffer[k];
}

I actually didn't consider the case of a leading zero, you make a good point there, a string would be more robust for my application. For some reason sscanf freezes my program if I try to pick the number out as a string (%s), even with predicting the leading and following chars in sscanf as before.

Unless I'm doing something wrong with sscanf, I'm happy to just use the brute force for loop :)

Once again, many thanks.

- Sam

10 Oct 2012

Hi Sam,

I'm glad you've found a solution. The most likely reason your program froze is an error whilst using pointers.

Steve

10 Oct 2012

Here's how I do it with my SIM900 module.

char *p = strstr(buffer,"+6");
strncpy(char_array, p, 12);


If you wanna get rid of the "+" in the front:

char *p = strstr(buffer,"+6")+1;
strncpy(char_array, p, 11);


Lerche

11 Oct 2012

Hello Lerche,

thanks for that, it looks like strstr() coupled with strncpy() will replace my 'for loops' nicely!

Have you heard of a way to get caller ID on the sim900 module instead of ...

\r\nRING\r\n

One would think that it would be a standard feature, but im struggling to find any information on it.

Best Regards,

Sam

08 Nov 2012

I've updated the firmware on my module, i'll see if I can find something about it.

Lerche

28 Nov 2012

I ran through the SIM900 AT command pdf, as far as I can tell, the command AT+CLCC, should list
Information on the current calls.

Lerche