A
arnuld
WANTED: To know the behavior of strtoul()
GOT: It works!
WHY POSTING: for improvements.
string contains a value which could be an int, long int or unsigned long
and I need to get that value using strtoul(). I have put error checks but
still I think I will get more advice on making it better:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
int str_to_ulongint(const char* str, unsigned long int* ulp);
int main(void)
{
unsigned long i = 127; /* initialize to some value to distinguish
between default and new values */
unsigned long i2 = 128;
/* unsigned long is 10 digits at maximum as per section 5.1.1 in H&s5 */
char arrc[11] = {0};
const char* arrc2 = "12345677899686848484";
int ret = sprintf(arrc, "%lu", ULONG_MAX);
if(EOF == ret || 0 > ret)
{
printf("sprintf() error\n");
exit(EXIT_FAILURE);
}
printf("i = %lu\narrc = %s, strlen(arrc): %u\n\n", i, arrc, strlen
(arrc));
if(0 > str_to_ulongint(arrc, &i))
{
printf("error converting values\n");
exit(EXIT_FAILURE);
}
printf("i = %lu\n\n", i);
printf("i2 = %lu\narrc2 = %s, strlen(arrc2): %u\n\n", i2, arrc2,
strlen(arrc2));
if(0 > str_to_ulongint(arrc2, &i2))
{
printf("error converting values\n");
exit(EXIT_FAILURE);
}
printf("i2 = %lu\n", i2);
return 0;
}
int str_to_ulongint(const char* str, unsigned long int* ulp)
{
int ret;
unsigned long int num;
char* p;
errno = 0;
if(NULL == str || '\0' == *str)
{
printf("Invalid Args\n");
return -1;
}
p = NULL;
num = strtoul(str, &p, 10);
/* Error check as per section 16.4 of H&S 5 */
if(ERANGE == errno)
{
if((0 == num) && (0 == strcmp(str, p)))
{
printf("strtoul() could not convert string\n");
}
else if(ULONG_MAX == num)
{
printf("strtoul() overflow error\n");
}
else
{
printf("strange output from strtoul()\n");
}
perror("*ERROR*");
ret = -1;
}
else if((0 == errno) && (NULL != p && '\0' == *p))
{
printf("Successful Conversion by strtoul()\n");
*ulp = num;
ret = 1;
}
else
{
printf( "strange conversions and errno values
\n");
printf( "num = %lu, ULONG_MAX = %lu", num, ULONG_MAX);
perror("*ERROR*");
ret = -1;
}
return ret;
}
============================= OUTPUT ===============================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra str-to-ulong.c
[arnuld@dune programs]$ ./a.out
i = 127
arrc = 4294967295, strlen(arrc): 10
Successful Conversion by strtoul()
i = 4294967295
i2 = 128
arrc2 = 12345677899686848484, strlen(arrc2): 20
strtoul() overflow error
*ERROR*: Numerical result out of range
error converting values
[arnuld@dune programs]$
GOT: It works!
WHY POSTING: for improvements.
string contains a value which could be an int, long int or unsigned long
and I need to get that value using strtoul(). I have put error checks but
still I think I will get more advice on making it better:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
int str_to_ulongint(const char* str, unsigned long int* ulp);
int main(void)
{
unsigned long i = 127; /* initialize to some value to distinguish
between default and new values */
unsigned long i2 = 128;
/* unsigned long is 10 digits at maximum as per section 5.1.1 in H&s5 */
char arrc[11] = {0};
const char* arrc2 = "12345677899686848484";
int ret = sprintf(arrc, "%lu", ULONG_MAX);
if(EOF == ret || 0 > ret)
{
printf("sprintf() error\n");
exit(EXIT_FAILURE);
}
printf("i = %lu\narrc = %s, strlen(arrc): %u\n\n", i, arrc, strlen
(arrc));
if(0 > str_to_ulongint(arrc, &i))
{
printf("error converting values\n");
exit(EXIT_FAILURE);
}
printf("i = %lu\n\n", i);
printf("i2 = %lu\narrc2 = %s, strlen(arrc2): %u\n\n", i2, arrc2,
strlen(arrc2));
if(0 > str_to_ulongint(arrc2, &i2))
{
printf("error converting values\n");
exit(EXIT_FAILURE);
}
printf("i2 = %lu\n", i2);
return 0;
}
int str_to_ulongint(const char* str, unsigned long int* ulp)
{
int ret;
unsigned long int num;
char* p;
errno = 0;
if(NULL == str || '\0' == *str)
{
printf("Invalid Args\n");
return -1;
}
p = NULL;
num = strtoul(str, &p, 10);
/* Error check as per section 16.4 of H&S 5 */
if(ERANGE == errno)
{
if((0 == num) && (0 == strcmp(str, p)))
{
printf("strtoul() could not convert string\n");
}
else if(ULONG_MAX == num)
{
printf("strtoul() overflow error\n");
}
else
{
printf("strange output from strtoul()\n");
}
perror("*ERROR*");
ret = -1;
}
else if((0 == errno) && (NULL != p && '\0' == *p))
{
printf("Successful Conversion by strtoul()\n");
*ulp = num;
ret = 1;
}
else
{
printf( "strange conversions and errno values
printf( "num = %lu, ULONG_MAX = %lu", num, ULONG_MAX);
perror("*ERROR*");
ret = -1;
}
return ret;
}
============================= OUTPUT ===============================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra str-to-ulong.c
[arnuld@dune programs]$ ./a.out
i = 127
arrc = 4294967295, strlen(arrc): 10
Successful Conversion by strtoul()
i = 4294967295
i2 = 128
arrc2 = 12345677899686848484, strlen(arrc2): 20
strtoul() overflow error
*ERROR*: Numerical result out of range
error converting values
[arnuld@dune programs]$