【问题标题】:Convert a string to an int with negative numbers将字符串转换为带负数的 int
【发布时间】:2018-11-11 13:15:07
【问题描述】:

我需要用 C 语言编写一个函数,将字符串(char * 指向的数据)转换为int。我已经用这段代码成功地做到了:

int charTOint(char * c) {
    char p = *c;
    int ergebnis = 0;

    while (p) {
        ergebnis = ergebnis * 10 + (p - '0');
        c++;
        p = *c;
    }

    return ergebnis;
}

我现在的问题是,我还需要它来处理以“-”开头的负数/字符数组。

我知道我必须检查第一个字符是否是“-”,但在那之后我被卡住了。

我知道 '-' 是 ASCII 表的第 45 个字符,但我想不出办法让它工作。

【问题讨论】:

    标签: c char int


    【解决方案1】:

    我已经用这个代码成功地完成了这个(肯定的):

    很好。一个重要的洞察力是在成功的基础上再接再厉。

    由于int charTOint(char * c) { 可以很好地处理正值,也许可以使用unsigned 重写它。我们得到更大的范围,因为UINT_MAX 通常大于INT_MAX

    unsigned charTOunsigned(const char * c) {
        char p = *c;
        unsigned ergebnis = 0;
        while (p) {
            ergebnis = ergebnis * 10 + (p - '0');
            c++;
            p = *c;
        }
        return ergebnis;
    }
    

    我还需要它来处理以“-”开头的负数/字符数组。

    现在有了charTOunsigned(),使用现有代码的变体重新制作满足附加目标的int charTOint()。使用 charTOunsigned() 通常的额外正数范围,int charTOint() 将很容易处理转换为 INT_MIN 的字符串。

    int charTOint(const char * c) {
      return (*c == '-') ? -charTOunsigned(c+ 1) : charTOunsigned(c);
    }
    

    当然可以编写一个独立的charTOint(),但我想强调代码重用。这使编码人员更有效率。

    【讨论】:

      【解决方案2】:

      可以添加另一个变量来识别符号。然后乘以符号变量。
      应添加检查以确认仅处理数字。如果输入是123abc,这将在123之后停止

      int charTOint(char * c) {
          char p = *c;
          int ergebnis = 0;
          int sign = 1;
      
          if ( '-' == *c || '+' == *c) {
              if ( '-' == *c) {
                  sign = -1;
              }
              c++;
          }
          while (*c) {
              p = *c - '0';
              if ( 0 <= p && 9 >= p) {// digit 0 to 9
                  ergebnis = ergebnis * 10 + p;
                  c++;
              }
              else {
                  break;//not a digit
              }
          }
      
          return ergebnis * sign;
      }
      

      编辑 3:

      #include <stdio.h>
      #include <string.h>
      #include <limits.h>
      
      int charTOint(char *c, int *number) {
          char p = *c;
          int sign = 1;
          int divmax = INT_MAX / 10;
          int divmin = INT_MIN / 10;
      
          *number = 0;
          while ( ' ' == *c || '\t' == *c) {
              c++;//skip leading spaces tabs
          }
          if ( '-' == *c || '+' == *c) {
              if ( '-' == *c) {
                  sign = -1;
              }
              c++;
          }
          while (*c) {
              p = *c - '0';
              if ( 0 <= p && 9 >= p) {// digit 0 to 9
                  if ( *number <= divmax && *number * 10 <= INT_MAX - p) {
                      *number = *number * 10 + p;
                      c++;
                  }
                  else {
                      if ( sign < 0 && *number * sign >= divmin && *number * sign * 10 >= INT_MIN + p) {
                          *number = *number * sign * 10 - p;
                          return 1;
                      }
                      fprintf ( stderr, "\n\t\tOVERFLOW\n\n");
                      *number = 0;
                      return 0;
                  }
              }
              else {
                  *number = 0;
                  return 0;//not a digit
              }
          }
      
          *number = *number * sign;
          return 1;
      }
      
      int main ( void) {
          char text[100] = "";
          int value = 0;
      
          do {
              printf ( "enter an integer or enter done\n");
              if ( fgets ( text, sizeof text, stdin)) {
                  text[strcspn ( text, "\n")] = 0;
                  if ( charTOint ( text, &value)) {
                      printf ( "value = %d\n", value);
                  }
                  else {
                      printf ( "input [%s]\n", text);
                  }
              }
              else {
                  fprintf ( stderr, "fgets EOF\n");
                  return 0;
              }
          } while ( strcmp ( text, "done"));
          return 0;
      }
      

      【讨论】:

      • 当结果应该是INT_MIN 因为ergebnis = ergebnis * 10 + p; 溢出时,效果很好。成功的结果取决于未定义的行为
      • 试试charTOint("2147483639")
      • Implementation of atoi() 可能是有用的阅读。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-15
      • 2017-03-23
      • 1970-01-01
      • 2011-10-02
      • 2011-03-06
      • 1970-01-01
      相关资源
      最近更新 更多