C - string to uint64_t casting with error handling

帅比萌擦擦* 提交于 2019-12-13 09:52:26

问题


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;
}

回答1:


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.



来源:https://stackoverflow.com/questions/46325780/c-string-to-uint64-t-casting-with-error-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!