在C和C++中将char转换为int

mai*_*ved 344 c c++ gcc

我如何转换charintC和C++?

Foo*_*Bah 481

取决于你想做什么:

要将值读作ascii代码,您可以编写

char a = 'a';
int ia = (int)a; 
/* note that the int cast is not necessary -- int ia = a would suffice */
Run Code Online (Sandbox Code Playgroud)

该字符转换'0' -> 0,'1' -> 1等等,你可以写

char a = '4';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */
Run Code Online (Sandbox Code Playgroud)

  • ia =(a - '0')%48; (11认同)
  • @ kevin001如果要将char转换为int并且字符"1"提供的ascii数字不是"1",则需要删除偏移量"0"以将其重新对齐以从0到9进行计数.连续数字1-9在ascii整数中相邻. (5认同)
  • 那个 - '0'技巧太棒了.帮了我很多忙. (5认同)
  • @KshitijBanerjee 这不是一个好主意,原因有两个:它在 '0' 之前给你一个 ascii 字符的负数(比如 `&` -> -10),它给你大于 10 的数字(比如 `x` -> 26) (2认同)
  • int ia = a - '0' - 这就是你所需要的 (2认同)

小智 79

那么,在ASCII码中,数字(数字)从48开始.你需要做的就是:

int x = (int)character - 48;
Run Code Online (Sandbox Code Playgroud)

  • 或者更具可读性:'`int x = character - '0'` (51认同)
  • @chad:不仅更具可读性,而且更具可移植性.C和C++不保证ASCII表示,但它们确保无论使用何种表示,10个十进制数字的表示都是连续的并且是按数字顺序排列的. (17认同)
  • 我唯一想改变的是48岁,这对“0”来说似乎有点“神奇” (2认同)

Mat*_*ner 58

C和C++总是至少提升类型int.此外,字符文字int在C和charC++中都是类型.

char只需指定一个类型即可转换类型int.

char c = 'a'; // narrowing on C
int a = c;
Run Code Online (Sandbox Code Playgroud)

  • -1答案对于问题的唯一有意义的解释是不正确的.这(代码`int a = c;`)将保留任何负值,C标准库函数无法处理.C标准库函数设置了将`char`值作为`int`处理的标准. (24认同)
  • @Matt:我保留了downvote.如果可能的话,我会加强它!你和其他人所假设的问题解释是没有意义的,因为它太过于微不足道了,而且因为对于OP的特定类型组合,存在一个不那么重要的非常重要的实际问题.你给出的建议对新手来说是直接危险的**.对于使用C标准库字符分类函数的程序,它很可能导致**未定义行为**.重新参考.对@ Sayam的回答,他删除了那个答案. (5认同)
  • 为此,您还可以使用非常不理解的**一元**`运算符+()`. (3认同)
  • -1表示错误:如果传递1252个高位字符,isupper()将有未定义的结果. (3认同)

Lun*_*din 29

char只是一个1字节的整数.char类型没有什么神奇之处!正如您可以为int指定short,或者为long指定int,您可以为int指定char.

是的,原始数据类型的名称恰好是"char",这暗示它应该只包含字符.但实际上,"char"只是一个糟糕的名字选择,可以混淆每个试图学习语言的人.更好的名称是int8_t,如果编译器遵循最新的C标准,则可以使用该名称.

当然,在进行字符串处理时,您应该使用char类型,因为经典ASCII表的索引适合1个字节.然而,您也可以使用常规的整数进行字符串处理,尽管在现实世界中没有任何实际原因可以帮助您实现这一目标.例如,以下代码将完美地运行:

  int str[] = {'h', 'e', 'l', 'l', 'o', '\0' };

  for(i=0; i<6; i++)
  {
    printf("%c", str[i]);
  }
Run Code Online (Sandbox Code Playgroud)

您必须意识到字符和字符串只是数字,就像计算机中的其他所有内容一样.当您在源代码中写入'a'时,它会被预处理为数字97,这是一个整数常量.

所以如果你写一个像这样的表达式

char ch = '5';
ch = ch - '0';
Run Code Online (Sandbox Code Playgroud)

这实际上相当于

char ch = (int)53;
ch = ch - (int)48;
Run Code Online (Sandbox Code Playgroud)

然后进行C语言整数提升

ch = (int)ch - (int)48;
Run Code Online (Sandbox Code Playgroud)

然后截断为char以适合结果类型

ch = (char)( (int)ch - (int)48 );
Run Code Online (Sandbox Code Playgroud)

在这些行之间有很多微妙的事情,其中​​char被隐含地视为int.

  • @RolandIllig 不,`char` 总是 1 个字节,如果给定系统上存在 `int8_t`/`uint8_t` 类型(这很可能),它们将能够适合 `char` 的结果,因为那么它将是 8 位。在高度奇特的系统上,例如各种过时的 DSP,`char` 将是 16 位,而 `uint8_t` 将不存在。编写与过时 DSP 兼容的代码是无稽之谈,编写与补码或符号和幅度系统兼容的代码也是无稽之谈。浪费时间,因为这样的系统在现实世界中几乎不存在。 (2认同)

Fre*_*urk 16

(这个答案解决了C++方面的问题,但C中也存在符号扩展问题.)

处理所有三种char类型(signed,unsignedchar)比首次出现时更精细.范围0到SCHAR_MAX(对于8位为127 char)的值很容易:

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
int n = c;
Run Code Online (Sandbox Code Playgroud)

但是,当somevalue超出该范围时,只有通过unsigned char才能为char所有三种类型中的"相同" 值提供一致的结果:

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
// Might not be true: int(c) == int(sc) and int(c) == int(uc).
int nc = (unsigned char)c;
int nsc = (unsigned char)sc;
int nuc = (unsigned char)uc;
// Always true: nc == nsc and nc == nuc.
Run Code Online (Sandbox Code Playgroud)

这在使用ctype.h中的函数时非常重要,例如isupperor toupper,因为符号扩展:

char c = negative_char;  // Assuming CHAR_MIN < 0.
int n = c;
bool b = isupper(n);  // Undefined behavior.
Run Code Online (Sandbox Code Playgroud)

注意通过int的转换是隐式的; 这有相同的UB:

char c = negative_char;
bool b = isupper(c);
Run Code Online (Sandbox Code Playgroud)

要解决这个问题,请通过safe_ctypeunsigned char包装ctype.h函数来轻松完成:

template<int (&F)(int)>
int safe_ctype(unsigned char c) { return F(c); }

//...
char c = CHAR_MIN;
bool b = safe_ctype<isupper>(c);  // No UB.

std::string s = "value that may contain negative chars; e.g. user input";
std::transform(s.begin(), s.end(), s.begin(), &safe_ctype<toupper>);
// Must wrap toupper to eliminate UB in this case, you can't cast
// to unsigned char because the function is called inside transform.
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为任何采用三种char类型中的任何一种的函数也可以采用其他两种char类型.它导致两个函数可以处理任何类型:

int ord(char c) { return (unsigned char)c; }
char chr(int n) {
  assert(0 <= n);  // Or other error-/sanity-checking.
  assert(n <= UCHAR_MAX);
  return (unsigned char)n;
}

// Ord and chr are named to match similar functions in other languages
// and libraries.
Run Code Online (Sandbox Code Playgroud)

ord(c)总是给你一个非负值 - 即使传递一个负数char或负数signed char- 并chr取任何值ord产生并给出完全相同的值char.

在实践中,我可能只是通过投unsigned char,而不是用这些,但他们简洁包裹投,提供了方便的地方加入错误检查int至- char,并会更短,更清晰,当你需要使用它们几次在附近.


her*_*tao 11

用途static_cast<int>:

int num = static_cast<int>(letter); // if letter='a', num=97
Run Code Online (Sandbox Code Playgroud)

编辑:你可能应该尽量避免使用(int)

int num =(int)letter;

检查为什么使用static_cast <int>(x)而不是(int)x?了解更多信息.


T.E*_*.D. 6

它取决于你的意思是"转换".

如果你有一系列代表整数的字符,比如"123456",那么在C中有两种典型的方法:使用像atoi()strtol()这样的特殊用途转换,或者通用的sscanf ().C++(实际上是一种伪装成升级的不同语言)增加了第三个字符串流.

如果您的意思是希望将其中一个int变量中的确切位模式视为a char,则更容易.在C中,不同的整数类型实际上比实际的单独"类型"更具有心态.刚开始在需要的地方使用它char,你应该没问题.您可能需要进行显式转换以使编译器偶尔停止抱怨,但所有应该做的就是删除超过256的任何额外位.


Hen*_*nke 5

我对nullC 有绝对的技能,但需要进行简单的分析:

char* something = "123456";

int number = parseInt(something);
Run Code Online (Sandbox Code Playgroud)

...这对我有用:

int parseInt(char* chars)
{
    int sum = 0;
    int len = strlen(chars);
    for (int x = 0; x < len; x++)
    {
        int n = chars[len - (x + 1)] - '0';
        sum = sum + powInt(n, x);
    }
    return sum;
}

int powInt(int x, int y)
{
    for (int i = 0; i < y; i++)
    {
        x *= 10;
    }
    return x;
}
Run Code Online (Sandbox Code Playgroud)

  • 此代码会快速调用未定义的行为,因此不适合复制和粘贴。(整数溢出) (3认同)