Friday, 19 April 2019

How to check the return value of sscanf

Check SScanf return value:


int sscanf(const char *str, const char *format, ...);

Description:

sscanf() reads its input from the character string pointed to by str
  1. sscanf return number of variable written into the buffer, so that we can check retun value with number of variable return
  2. we could not do the same in snprint, because it return the number buffer writting, 
      Example : Suppose write (%s,%s, "Vel", "kutralam"), then sscanf return 2 since 2 variable is written, but snprintf return 11 because it return number of character written

hh modifier:


As for h, but the next pointer is a pointer to a signed char or unsigned char.
This hh modifier is used to print the mac address(octal)

Return:

  Return the number of input items successfully matched and assigned.
  Which can be fewer than provided for, or even zero in the event of an early matching failure.


Program:


/* Sscanf return value checker by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

int main()
{
    int ret = 0;
    unsigned char mac_addr[6] = {0};
    char *mac_value_buf = NULL;
    unsigned int int_value[6];
    int count = 0;
    char str[256] = {0};
//    uint32_t new;

    do {
    if (count == 0) {
        mac_value_buf = "000C2956BAF5,1,2,3,4,5,6";
    } else {
        mac_value_buf = "000C2956:BAF5,1,2,3,4,5";
    }
    count++;
    printf("\n\n\t\t ************* Mac buff value = %s Start ****************\n", mac_value_buf);

    /* Here using 04d, this is not needed */
    ret = sscanf(mac_value_buf, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx,%04d,%04d,%04d,%04d,%04d,%04d",
            &mac_addr[0], &mac_addr[1],
            &mac_addr[2], &mac_addr[3],
            &mac_addr[4], &mac_addr[5],
            &int_value[0], &int_value[1],
            &int_value[2], &int_value[3],
            &int_value[4], &int_value[5]);
    /*
     * Reading 12 variable, so sscanf return 12 then all the values are read successfully,
     * and no error, otherwise error in reading
     */

    if (ret != 12) {
        printf("Error in retrieve the data from buffer mac_value_buf = %s \n", mac_value_buf);
    } else {
        printf("sscanf ret = %d dev inf = %d inf[5] = %d \n", ret, int_value[0], int_value[5]);
    }

     memset(int_value, 0, sizeof(int_value));

     /* Here using %d, this is enough */
     ret = sscanf(mac_value_buf, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx,%d,%d,%d,%d,%d,%d",
             &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], &mac_addr[4], &mac_addr[5], &int_value[0],
             &int_value[1], &int_value[2], &int_value[3], &int_value[4], &int_value[5]);

     printf("sscanf to skip ret = %d dev inf = %d inf[5] = %d errno = %d \n", ret, int_value[0], int_value[5], errno);

     /*
      * Here trying to skip the mac & start read from comma, but sscanf is not working this module,
      * it will fail and won't retrieve any value.
      */
     ret = sscanf(mac_value_buf, ",%u,%u,%u,%u,%u,%u",
//             &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], &mac_addr[4], &mac_addr[5], &int_value[0],
             &int_value[0],
             &int_value[1], &int_value[2], &int_value[3], &int_value[4], &int_value[5]);
     printf("sscanf to skip ret = %d dev inf = %d inf[5] = %d errno = %d \n", ret, int_value[0], int_value[5], errno);


     /* snprintf return number of bytes read not an number variable so could not add if check */
     ret = snprintf(str, sizeof(str), "%02X:%02X:%02X:%02X:%02X:%02X,%04d,%04d,%04d,%04d,%04d,%04d",
            mac_addr[0], mac_addr[1],
            mac_addr[2], mac_addr[3],
            mac_addr[4], mac_addr[5],
            int_value[0], int_value[1],
            int_value[2], int_value[3],
            int_value[4], int_value[5]);
    /*
      * we could not check 12 with snprintf because snprintf calculate number bytes is writing,
      * not a number variable is writing, here value change from 45 to 50 based on number of digit in dev_info
      */
     printf("snprintf ret = %d \n", ret);
     printf("\t\t************* Mac buff value = %s END ****************\n", mac_value_buf);

    } while (count < 2);


     return 0;
}

Output:

 sample$ ./a.out
                 ************* Mac buff value = 000C2956BAF5,1,2,3,4,5,6 Start ****************
sscanf ret = 12 dev inf = 1 inf[5] = 6
sscanf to skip ret = 12 dev inf = 1 inf[5] = 6 errno = 0
sscanf to skip ret = 0 dev inf = 1 inf[5] = 6 errno = 0
snprintf ret = 47
                ************* Mac buff value = 000C2956BAF5,1,2,3,4,5,6 END ****************


                 ************* Mac buff value = 000C2956:BAF5,1,2,3,4,5 Start ****************
Error in retrieve the data from buffer mac_value_buf = 000C2956:BAF5,1,2,3,4,5
sscanf to skip ret = 4 dev inf = 0 inf[5] = 0 errno = 0
sscanf to skip ret = 0 dev inf = 0 inf[5] = 0 errno = 0
snprintf ret = 47
                ************* Mac buff value = 000C2956:BAF5,1,2,3,4,5 END ****************

No comments:

Post a Comment