首页 > 解决方案 > C++ 将字符类型转换为 int 类型

问题描述

因此,我阅读并被告知从给定字符中减去“0”会将其转换为 int,但是我的 Visual Studio 在这里没有认识到这一点,说“const char *”类型的值不能用于初始化实体在此处输入 C++ 编程中的 int。

bigint::bigint(const char* number) : bigint() {


int number1 = number - '0'; // error code
for (int i = 0; number1 != 0 ; ++i)
{
    digits[i] = number1 % 10;
    number1 /= 10;
    digits[i] = number1;
}
}

前半部分的目标是将给定的数字简单地转换为 int 类型。后半部分是向后输出该数字,没有前导零。请注意,此函数是此处头文件中声明的类的一部分:

 class bigint {
    
    public:
      static const int MAX_DIGITS = 50;
    
    private:
      int digits[MAX_DIGITS];
    
    public:
    
      // constructors
      bigint();
      bigint(int number);
      bigint(const char * number);
}
  

有什么方法可以将 char 参数转换为 int 以便我可以输出 int 吗?不使用 std 库或 strlen,因为我知道有一种方法可以使用 '0' 字符,但我似乎做错了。

标签: c++classcharinteger

解决方案


我不知道你的理解是什么,所以我将回顾一下我在代码片段中看到的所有内容。

首先,您传递给函数的是指向 char的指针,如果您愿意,可以使用const关键字使char不可变或“只读”。

Achar实际上是一个 8 位大小的1整数。它可以存储二进制形式的数值,也可以解释为字符。

基本类型 - cppreference.com

标准还期望char成为“字符表示的类型”。它可以用 ASCII 码表示,但也可能是 EBCDIC 之类的东西,我不确定。为了将来参考,请记住不能保证 ASCII,尽管您可能永远不会使用没有 ASCII 的系统(如果我是正确的)。但 char 并没有以某种方式强制编码 - 它是您将这些 char 和 char 指针传递给的函数,它们将它们的内容解释为 ASCII 编码中的字符,而在一些晦涩或遗留平台上,它们实际上可以将它们解释为字符一些不太常见的编码。然而,标准要求使用的编码具有此属性:字符 '0' 到 '9' 的代码是后续的,因此 '9' - '0' 意味着:从 ' 的代码中减去 '0' 的代码 9'。结果是 9,因为 '9' 的代码是 ASCII 中的 '0' 代码的 9 个位置。范围 'a'-'z' 和 'A'-'Z' 也具有这种质量,以防万一,但如果您的输入以高于 10 为基数,例如流行的以 16 为基数,那就有点棘手了称为十六进制。

指针存储一个地址,因此它最基本的功能是“指向”一个变量。但它可以以多种方式使用,其中一种在 C 中非常常见的方式是存储相同类型变量数组的开头地址。那些可能是字符。我们可以将这样的数组解释为一行文本或一个字符串(一个概念,不要与 C++ 特定的字符串类混淆)。

由于指针不包含有关此类数组的长度或结尾的信息,因此我们需要将该信息传递给我们将指针传递给的函数。有时我们可以只提供长度,有时我们提供结束指针。在处理“文本行”或 c 风格的字符串时,我们使用(和 c 标准库函数期望的)所谓的空终止字符串。在这样的字符串中,char用于一行的最后一个之后的第一个是null,为了简化,基本上是一个 0。一个 0,但不是一个 '0'。

因此,您传递给函数的内容,以及您解释为 416 的内容,实际上是指向内存中某个位置的指针,其中“4”被计算并存储为数字,然后是“1”,然后是“6” ,占用三个字节。并且根据您获得这行文本的方式,“6”可能后跟一个 NULL,即 - 一个零。 NULL - cppreference.com

将这样的字符串转换为数字首先需要能够保存它的数据类型。在 416 的情况下,它可能是从上到下的任何东西short。如果您想自己执行此操作,则需要遍历整行文本并添加乘以 10 的适当幂的数字,还要注意签名,并可能检查是否存在任何边缘情况。但是,您可以使用标准功能,例如int atoi (const char * str); atoi - cplusplus.com

现在,这当然很好,但是您正在尝试使用“bigints”。无论您如何定义它们,这意味着您的类的目的是处理要存储在内置类型中的大数字。因此,您无法像那样转换它们。

您现在尝试做的似乎是一个构造函数,它创建一个 bigint 表示为 ac 样式字符串的数字。我该怎么说...您想在内部将您的 bigint 存储为以 10 为底的数字数组(对于代码简单性、可读性和可维护性以及与以 10 为底的文本表示的互操作性而言,这是一个不错的选择,但它没有t 有效利用内存和处理能力。)并且您的输入也是以 10 为底的数字数组,除了在内部您将数字存储为数字,而您的输入是编码字符。你需要:

  1. 清理输入(你需要什么样的输入是可以接受的标准,fe。如果可以有任何前导或尾随空格,数字后面是否可以跟任何要丢弃的非数字字符,如何表示签名,是+积极的数字可选或禁止等,如果输入无效则抛出异常。
  2. 将您为输入强制执行的任何标准转换为您在内部使用的任何统一标准,fe。去除前导空格,+如果它是可选的并且你不在内部使用它,则删除符号等。
  3. 当您知道内部数组中的哪些位置与输入字符串中的哪些位置相对应时,您可以对其进行迭代并复制每个数字,首先从 ASCII 解码它。

附注 - 我不能确定你期望你的输入到底是什么,因为它很可能是一个文本表示 - 因为它很容易成为一个未编码的字符数组。当然,显然是前者,因为你的帖子,我知道,但函数原型(返回类型和参数类型的行)并不能向任何人保证这一点。只是另一件需要注意的事情。希望这个答案可以帮助您了解那里发生的事情。

PS。我不能足够强烈地强调您的代码的最大问题是即使这条线有效:

int number1 = number - '0'; // error code

您将尝试将 10^50 数量级的数字存储到能够保持 10^9 数量级的变量中

这个问题的关键部分,我有一种模糊的感觉,你可能在 spoj.com 上发现了你正在处理 BIGints。整数太大而无法以微不足道的方式存储。

1)该标准实际上并不要求 char 直接具有此大小,但间接要求它至少为 8 位,在晦涩的平台上可能更多。是的,我认为有些平台确实超过 8 位。对于在晦涩的架构上可能表现得很奇怪的指针也是如此。


推荐阅读