C 将数字转换为整数

C 将数字转换为整数,c,int,type-conversion,C,Int,Type Conversion,我需要得到一个可能超出有符号整数范围的数字,从字符串到整数。如果值超出有符号整数限制,我总是得到数字0。我理解0表示转换失败 以下是我尝试过的: 现在数据总是在int限制下,所以将其存储到int中应该不会有问题。即使将类型更改为long,我仍然得到0 int getData(char* data){ char *end; unsigned int x = strtol (data, &end, 7); return x; } 我试着将值转换成无符号整数,然后返回

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

以下是我尝试过的:

现在数据总是在int限制下,所以将其存储到int中应该不会有问题。即使将类型更改为long,我仍然得到0

int getData(char* data){
    char *end;
    unsigned int x = strtol (data, &end, 7);
    return x;
}
我试着将值转换成无符号整数,然后返回到无符号整数。没关系,我甚至没有得到正确的转换

int getData(char* data){
    unsigned x = atoi(data);
    return x;
}
我还尝试了在另一个堆栈交换线程上找到的方法。这里也不走运

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

我做错了什么

尽管您的代码有点奇怪,但它应该可以工作。但是
strtol
返回一个
long
,因此需要做更多的工作才能正确获得
无符号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);
}
#包括
#包括
#包括
#包括
#包括
//使用“long”更清晰一些,根据您的需要进行调整
长getData(字符*数据)
{
字符*结束;
//使用前重置错误号。
errno=0;
//此处未使用变量“end”
长x=strtol(数据和结束,10);
//从主页
if((errno==ERANGE&&(x==LONG_MAX | | x==LONG_MIN))
||(错误号!=0&&x==0)){
//为调用者设置errrno(这不是最好的主意,
//此函数应返回自己的错误变量)
errno=ERANGE;
返回LONG_MIN;
}
返回x;
}
//获取无符号整数的示例
无符号整型getUData(字符*数据)
{
字符*结束;
//使用前重置错误号。
errno=0;
//改为使用strtoul()
无符号长x=strtoul(数据和结束,10);
//从主页
if((errno==ERANGE&&(x==ULONG_MAX))
||(错误号!=0&&x==0)){
//为调用者设置errrno(这不是最好的主意,
//此函数应返回自己的错误变量)
errno=ERANGE;
返回UINT_MAX;
}
//检查它是否适合无符号整数
如果(x>UINT_MAX){
//当然,应该返回不同的错误
厄尔诺=以东;
返回UINT_MAX;
}
返回(无符号整数)x;
}
int main(int argc,字符**argv)
{
长ret;
无符号整数;
如果(argc!=2){
fprintf(stderr,“用法:%s整数\n”,argv[0]);
退出(退出失败);
}
//重置错误号
errno=0;
//转换输入
ret=getData(argv[1]);
//检查错误
如果(ret==LONG\u MIN&&errno!=0){
fprintf(stderr,“试图将%s转换为长文件时出错,\n”,argv[1]);
退出(退出失败);
}否则{
printf(“getData(%s)返回%ld\n”,argv[1],ret);
}
//重置错误号
errno=0;
//转换输入
uret=getUData(argv[1]);
//检查错误
如果(uret==UINT\u MAX&&errno!=0){
fprintf(stderr,“试图将%s转换为无符号整数时出错”,argv[1]);
退出(退出失败);
}否则{
printf(“getUData(%s)返回%u\n”,argv[1],uret);
}
退出(退出成功);
}
如果,我将所有支票放入一个
;你可能会发现把它们分开是一个更好的主意,这样可以从中获得更多的信息来发现你的错误

我理解0表示转换失败

不完全是

如果strto*()
返回0,则

  • 转换成功,字符串类似于
    “0”
    “0”

  • 转换失败。字符串类似于
    ”--123“
    “abc”

  • 要进行区分,请测试
    endptr
    。带有错误消息的更健壮的
    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;
    }
    
    int-getData(const-char*data){
    char*endptr;
    errno=0;
    长x=strtol(数据和结束,10);
    //这是OP查找问题所需的缺失代码
    如果(数据==结束){
    printf(“无转换”,数据);
    }else if(errno){
    printf(“溢出/实现定义的错误,%d,\n”,errno==erage,data);
    }
    如果(xINT_最大值){
    printf(“溢出(长到整数),%ld\n”,x,数据);
    x=x<0?最小整数:最大整数;
    errno=ERANGE;
    }
    返回(int)x;
    }
    

    我怀疑OP的代码是1)没有使用预期的字符串调用
    getData()
    ,或者2)OP的代码没有正确打印返回值。

    您确定要使用
    strtoul(data,NULL,7)
    将结果设置为
    base 7
    ,我认为应该是
    strtoul(data,NULL,10)
    很好,但是如果我用10替换它也没关系。让我们知道你从这段代码中得到了什么以及你期望得到什么如果你想将字符串转换成整数,你必须将
    strtoul
    base设置为base 10。是否希望base 7使用此
    strtol(数据,&end,7)您需要阅读手册页,我希望得到的数字不是0。我选择什么基地都不重要。我总是得到0分。例如,如果数据包含3147483647,我想在名为x的无符号整数中看到该数字。
    
    #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);
    }