将数字转换为整数

时间:2017-04-17 00:18:52

标签: c int type-conversion

我需要得到一个可能超出有符号整数范围的数字,从字符串到整数。如果值超出有符号整数限制,我总是得到数字0。我知道0表示转换失败。

这是我尝试过的:

现在数据总是在int限制之下,因此将其存储到int应该不是问题。即使将类型更改为长,我仍然会得到0。

int getData(char* data){
    char *end;
    unsigned int x = strtol (data, &end, 7);
    return x;
}

我已经尝试将值放入unsigned int并返回unsigned int。没关系我甚至没有得到正确的转换。

int getData(char* data){
    unsigned x = atoi(data);
    return x;
}

我也试过这个,我在另一个堆栈交换线程上找到了。这里也没有运气。

int getData(char* data){
    int x = strtoul(data, NULL, 10);
    return x;
}

我做错了什么?

2 个答案:

答案 0 :(得分:2)

  

我知道0表示转换失败。

不完全。

如果"0"返回0,则

  1. 转化成功,字符串类似于" 0"""

  2. 转换失败。字符串类似于"--123""abc"endptr

  3. 要区分,请测试getData()。下面是一个更健壮的int getData(const char* data){ char *endptr; errno = 0; long x = strtol (data, &end, 10); // This is the missing code needed for OP to locate the issue if (data == end) { printf("No conversion <%s>\n", data); } else if (errno) { printf("Overflow/implementation defined error, %d, <%s>\n", errno == ERANGE, data); } if (x < INT_MIN || x > INT_MAX) { printf("Overflow (long to int), %ld <%s>\n", x, data); x = x < 0 ? INT_MIN : INT_MAX; errno = ERANGE; } return (int) x; } 错误消息:

    getData()

    我怀疑OP的代码是1)没有使用预期的字符串调用var newTodo = document.createElement('li') .appendChild(document.createElement('p')) .appendChild(document.createTextNode(task)) 或2)OP的代码没有正确打印返回的值。< / p>

答案 1 :(得分:1)

虽然你的代码有点奇怪,但它应该可行。但strtol会返回long,因此需要更多工作才能正确获得unsigned int

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

// using "long" for a bit more clarity, adapt according to your needs
long getData(char *data)
{
  char *end;
  // reset errno before use.
  errno = 0;
  // variable "end" unused here
  long x = strtol(data, &end, 10);
  // from the manpage
  if ((errno == ERANGE && (x == LONG_MAX || x == LONG_MIN))
      || (errno != 0 && x == 0)) {
    // set errrno for caller (not the best idea here, 
    // this function should return its own error variable)
    errno = ERANGE;
    return LONG_MIN;
  }
  return x;
}
// example to get an unsigned int
unsigned int getUData(char *data)
{
  char *end;
  // reset errno before use.
  errno = 0;
  // use strtoul() instead
  unsigned long x = strtoul(data, &end, 10);
  // from the manpage
  if ((errno == ERANGE && (x == ULONG_MAX))
      || (errno != 0 && x == 0)) {
    // set errrno for caller (not the best idea here, 
    // this function should return its own error variable)
    errno = ERANGE;
    return UINT_MAX;
  }
  // check if it fits into an unsigned int
  if(x > UINT_MAX ){
    // should return a different error, of course
    errno = EDOM;
    return UINT_MAX;
  }

  return (unsigned int)x;
}


int main(int argc, char **argv)
{
  long ret;
  unsigned int uret;

  if (argc != 2) {
    fprintf(stderr, "Usage: %s integer\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  // reset errno
  errno = 0;
  // get the input transformed
  ret = getData(argv[1]);
  // check for errors
  if (ret == LONG_MIN && errno != 0) {
    fprintf(stderr, "An error occured while trying to transform %s to a long\n", argv[1]);
    exit(EXIT_FAILURE);
  } else {
    printf("getData(%s) returned %ld\n", argv[1], ret);
  }

  // reset errno
  errno = 0;
  // get the input transformed
  uret = getUData(argv[1]);
  // check for errors
  if (uret == UINT_MAX && errno != 0) {
    fprintf(stderr, "An error occured while trying to transform %s to an unsigned int\n", argv[1]);
    exit(EXIT_FAILURE);
  } else {
    printf("getUData(%s) returned %u\n", argv[1], uret);
  }

  exit(EXIT_SUCCESS);
}

我将所有支票放入一个if;您可能会发现将它们分开以获取更多信息以找出错误是一个更好的主意。