-1

This program is to cast strings to uint64_t types and get the errors if any.

It should output, in this case, 2 errors (overflow and negative number), none of which appear. Also, it doesn't properly cast one of the strings.

Any help would be appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>
#include <limits.h>

int func(const char *buff) {
    char *end;
    int si;

    errno = 0;

    const uint64_t sl = strtoull(buff, &end, 10);

    if (end == buff) {
    fprintf(stderr, "%s: not a decimal number\n", buff);
    } else if ('\0' != *end) {
    fprintf(stderr, "%s: extra characters at end of input: %s\n", buff, end);
    } else if ((sl < 0 || ULONG_MAX == sl) && ERANGE == errno) {
    fprintf(stderr, "%s out of range of type uint64_t\n", buff);
    } else if (sl > ULONG_MAX) {
    fprintf(stderr, "%ld greater than ULONG_MAX\n", sl);
    } else if (sl < 0) {
     fprintf(stderr, "%ld negative\n", sl);
    } else {
    si = (int)sl;
    }

    return si;
}

int main()
{

    printf("%d\n", func("123456789123465789"));
    printf("%d\n", func("123456789123465789123465789"));
    printf("%d\n", func("-1"));


    return 0;
}
akshayk07
  • 2,092
  • 1
  • 20
  • 32
PyCV
  • 315
  • 2
  • 11

1 Answers1

0

strtoull(); allows input that begin with '-'. The function converts the numeric portion of the text and then negates it, the result is still an unsigned integer. So code cannot use the result of strtoull() to determine if the text represented a negative number as with uint64_t sl;, sl < 0 is always false.

Code needs to detect the '-' in other ways.

I'd expect the function to return an uint64_t

#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>

// int func(const char *buff) {
uint64_t func(const char *buff) {
  const char *s = buff;
  // consume leading whitespace
  while (isspace((unsigned char ) *s)) {
    s++;
  }
  int sign = *s;
  if (sign == '-' || sign == '+') {
    s++;
  }
  // Now code knows it the text is "negative"

  // rest of OP's code needs a some work
  char *end;
  errno = 0;
  unsigned long long sl = strtoull(s, &end, 10);

  if (end == s) {
    fprintf(stderr, "%s: not a decimal number\n", buff);
  } else if ('\0' != *end) {
    fprintf(stderr, "%s: extra characters at end of input: %s\n", buff, end);
    // } else if ((sl < 0 || ULONG_MAX == sl) && ERANGE == errno) {
  } else if (sign == '-') {
    fprintf(stderr, "%s negative\n", buff);
    sl = 0;
    errno = ERANGE;
  } else if (ERANGE == errno) {
    fprintf(stderr, "%s out of range of type uint64_t\n", buff);

    // Only needed on rare machines
#if ULLONG_MAX > UINT64_MAX
    else if (sl > UINT64_MAX) {
      fprintf(stderr, "%s out of range of type uint64_t\n", buff);
      sl = UINT64_MAX;
      errno = ERANGE;
    }
#endif

  }
  return (uint64_t) sl;
}

OP's returning of an int is strange. Leave updating main() to OP.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256