Wednesday, 26 June 2019

strtol - convert str to interger


strtol - Convert the number from string into interger

NAME

  • strtol, strtoll, strtoq - convert a string to a long integer

SYNOPSIS

       #include <stdlib.h>

       long int strtol(const char *nptr, char **endptr, int base);
       long long int strtoll(const char *nptr, char **endptr, int base);

       strtoll():
           _ISOC99_SOURCE
               || /* Glibc versions <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

DESCRIPTION  

  • The strtol() function converts the initial part of the string in nptr to a long integer value according to the given base.
  • If base is 2 then binary, if 8 then octal, if 10 then decimal & 16 for hexa decimal.
  • In bases above 10, the letter 'A' in either uppercase or lowercase represents 10, 'B' represents 11, and so forth, with 'Z' representing 35.
  • Checked in sample program, Hence If u give base as 20 then, f as 15, g as 16, h as 17... j as 19, k will throw an error.
  •  
  • If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr.
  • If there were no digits at all, strtol() stores the original value of nptr in *endptr (and returns 0).

RETURN VALUE

  • The strtol() function returns the result of the conversion, unless the value would underflow or overflow.
  • If an underflow occurs, strtol() returns LONG_MIN.
  • If an overflow occurs, strtol() returns LONG_MAX.
  • In both cases, errno is set to ERANGE.

Note: Program should set errno to 0 before the call, after call check the errno.

Difference between atoi, strtol & sscanf :

atoi()
    Pro: Simple.
    Pro: Convert to an int.
    Pro: In the C standard library.
    Pro: Fast.
    Con: No error handling.
    Con: Handle neither hexadecimal nor octal.

atol()
    Pro: Simple.
    Pro: In the C standard library.
    Pro: Fast.
    Con: Converts to an long, not int which may differ in size.
    Con: No error handling.
    Con: Handle neither hexadecimal nor octal.

strtol()
    Pro: Simple.
    Pro: In the C standard library.
    Pro: Good error handling.
    Pro: Fast.
    Con: Convert to an long, not int which may differ in size.

strtoul()
    Pro: Simple.
    Pro: In the C standard library.
    Pro: Good error handling.
    Pro: Fast.
    ---: Appears to not complain about negative numbers.
    Con: Converts to an unsigned long, not int which may differ in size.

sscanf(..., "%i", ...)
    Pro: In the C standard library.
    Pro: Converts to int.
    ---: Middle-of-the-road complexity.
    Con: Slow.
    Con: OK error handling (overflow is not defined).
    #define BASE_DECIMAL             10
Eg: pid_count = (int)strtol(buf, NULL, BASE_DECIMAL);

Program:

/* strtol - convert str to interger by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>>
#include <errno.h>  // errno & ERANGE
#include <stdlib.h>  // strtol & LONG_MAX
#include <limits.h>  // LONG_MAX & LONG_MIN
#include <string.h>  // for strerror

enum {
    FAILED = -1,
    SUCCESS,
};

/*************************************************************************************
 * FUNCTION NAME: convert_str_to_int
 *
 * DESCRIPTION  : convert the string into interget value
 *
 * RETURNS      : None
 * RETURNS      : FAIL on failure,
 *                SUCCESS on successfull update.
 *************************************************************************************/
static int convert_str_to_int(char *str_val, unsigned int *conv_value, char **save_endptr)
{
    char *endptr = NULL;
    long int result = 0;

    if (!str_val || !conv_value) {
        printf("input string is NULL \n");
        return FAILED;
    }

   errno = 0;
    result = strtol(str_val, &endptr, 10);
    *conv_value = (unsigned int)result;
    if (((errno == ERANGE) && ((result == LONG_MAX) || (result == LONG_MIN))) ||
            ((errno != 0) && (result == 0))) {
        printf("Error: conversion %s(%d) \n", strerror(errno), errno);
        return FAILED;
    }

    /* Save the endptr string for any future usage, after conversion. */
    if (save_endptr) {
        *save_endptr = endptr;
        if ((*save_endptr) && (**save_endptr != '\0') &&
                (!isspace(**save_endptr))) {
            printf("End string of input value saved as:%s \n", *save_endptr);
        }
    }

    if (endptr == str_val) {
        printf("No digits were found \n");
        return FAILED;
    }


    return SUCCESS;
}

int main()
{
    int      value = 0;
    char     *endptr = NULL;
    char     str[32] = {0};

    while (1) {
        printf("Enter the number to convert strint to int   :   ");
//        scanf("%[^\t\n]s", str);
        fgets(str, sizeof(str), stdin);
        convert_str_to_int(str, &value, &endptr);
        /*
         * Check the endptr has any invalid trailing strings,
         * after strtol conversion.
         */
        if ((endptr) && (*endptr != '\0') && (!isspace(*endptr))) {
            printf("Error invalid string is present \n");
        } else {
            printf("Input value    :  %s", str);
            printf("Value after convert val to : %d\n",value);
        }
    }

        convert_str_to_int("5m", &value, &endptr);
    if ((endptr) && (*endptr != '\0') && (!isspace(*endptr))) {
        printf("Error invalid string is present for 5m \n");
    } else {
        printf("Value after conver 5m val : %d \n", value);
    }

    return 0;
}



Output: 

 velraj@virtual-machine:~/velrajk/sample$ ./a.out
Enter the number to convert strint to int   :   5
Input value    :  5
Value after convert val to : 5
Enter the number to convert strint to int   :   5m
End string of input value saved as:m

Error invalid string is present
Enter the number to convert strint to int   :   5
Input value    :  5
Value after convert val to : 5
Enter the number to convert strint to int   :   5    m
Input value    :  5    m
Value after convert val to : 5
Enter the number to convert strint to int   :   5 mnews
Input value    :  5 mnews
Value after convert val to : 5
Enter the number to convert strint to int   :   ^C
 

No comments:

Post a Comment