自定义 strtoi 函数编译时问题

Custom strtoi function compile time issue

我正在尝试实现一个非常简单的 strtoi 功能。当动态创建传递的参数时它工作正常(下面的案例 2)。但是,如果 char 是由在编译时分配的 char[] 创建的,我会在 len 上得到一个常量值,因为 std::strlen(ch) 打乱了我的逻辑,我找不到一个解决方案。

 int strtoi(char* ch)
 {   
  int sum {0};
  int len = static_cast<int>(std::strlen(ch));
  int skipLast = static_cast<int>(static_cast<int>(ch[0]) == 45);

  //Integer Method
  for(int i = len - 1; i >= 0 + skipLast; i--)
  {
    if(static_cast<int>(ch[i]) < 48 || static_cast<int>(ch[i]) > 57)
      return 0;
    sum += (ch[i]-48) * std::pow(10,i-skipLast);
  }

   sum = skipLast == 1 ? -sum : sum;
   return sum;
 }

int main()
{
  char pos[3] {'1','2','3'};
  std::cout << strtoi(pos) << std::endl;
  char neg[4] {'-','1','2','3'};
  std::cout << strtoi(neg) << std::endl;
  return 0;
}

Returns:0-123。我的函数中的 len 变量没有获得第一次调用的预期值,我认为这是因为 neg[4] 分配的内存比 pos[3] 多。然而,对于第二种情况:

int main()
{
  char* pos;
  pos = new char[3] {'1','2','3'};
  std::cout << strtoi(pos) << std::endl;
  char* neg;
  neg = new char[4] {'-','1','2','3'};
  std::cout << strtoi(neg) << std::endl;
  return 0;
}

Returns123,-123。预期的结果。 我猜这是因为在第一种情况下,编译器根据 char[4] 数组为函数及其参数分配内存。这个对吗? 第二种情况如何工作,编译器如何为动态变量的函数分配内存? 使该功能适用​​于这两种情况的可能解决方案是什么? 在此先感谢您的帮助。

strlen 要求字符串以 null 结尾,像这样:

char* pos = new char[4] {'1','2','3','[=10=]'};
std::cout << strlen(pos) << "\n";  // Shows "3"

添加这个空终止符有一个简写方式:

const char[] pos = "123";
std::cout << strlen(pos) << "\n";  // Shows "3"
std::cout << sizeof(pot) << "\n";  // Shows "4"

我为pos使用了数组类型只是为了说明它真的是4个字符;您可以改用 const char*(实际上这很典型),但是 sizeof 行将不起作用。

请注意,如果你像这样分配一个字符串文字,那么你以后不能在它上面使用 delete,而你可以(并且应该)使用 delete 如果你使用 new,或 delete[] 数组。

你遇到的问题是你忘记了 char 字符串在 C++ 中真的叫做 null-terminated 字节字符串 .

null-terminator 是所有标准字符串函数(如 std::strlen)将寻找的字符串结束位置。

您的字符串 不是 空终止的,因此将它们传递给例如std::strlen 将导致 undefined behavior,因为它们超出数组或分配的内存范围,寻找这个不存在的空终止符。

要解决该问题,您需要确保所有字符串都以 null 结尾:

// will create pos as an array of *four* characters, the last being the null-terminator
char pos[] = "123";

我修改了你的代码如下:

int strtoi(char* ch, int len)
{
    int sum{ 0 };
    //int len = (std::strlen(ch));
    int skipLast = static_cast<int>(static_cast<int>(ch[0]) == 45);

    //Integer Method
    for (int i = len - 1; i >= 0 + skipLast; i--)
    {
        if (static_cast<int>(ch[i]) < 48 || static_cast<int>(ch[i]) > 57)
            return 0;
        sum += (ch[i] - 48) * std::pow(10, i - skipLast);
    }

    sum = skipLast == 1 ? -sum : sum;
    return sum;
}

int main()
{
    char pos[3]{ '1','2','3' };
    std::cout << strtoi(pos, 3) << std::endl;
    char neg[4]{ '-','1','2','3' };
    std::cout << strtoi(neg, 4) << std::endl;
    return 0;
}

strtoi 无法计算函数内的数组长度。你必须用数组指针传递它,因为没有 '\0' 字符。 这就是为什么当您将数组传递给函数时,您还必须传递数组大小或长度。

上述修改代码的输出:

321

-321