【问题标题】:LOGIC of Converting a "char" into an "int" in C在 C 中将“char”转换为“int”的逻辑
【发布时间】:2018-08-08 11:18:57
【问题描述】:

大家!

请帮助我理解以下问题... 所以我会有一个字符串类型的音符输入,看起来像“A5”或“G#2”或“Cb4”等。我需要提取一个八度索引,即最后一个数字“5”或“2” " 或 "4"... 提取后我需要它作为 int 类型。

所以我这样做了:

string note = get_string("Input: ");
int octave = atoi(note[strlen(note) - 1]);
printf("your octave is %i \n", octave);

但是它给了我一个错误“错误:不兼容的整数到指针转换将'char'传递给'const char *'类型的参数;使用& [-Werror,-Wint-conversion]获取地址”

然后我尝试从函数中排除数学,然后这样做:

int extnum = strlen(note) - 1;
int octave = atoi(note[extnum]);

效果也不好。所以我对 atoi 函数进行了研究,但我不明白......

  1. ATOI 需要一个字符串 (CHECK)
  2. 将其转换为整数,而不是 ASCII 含义 (CHECK)
  3. atoi 函数库 (CHECK)

我基本上在问“取该字符串的第 n 个字符并将其设为 int”。

在谷歌上搜索了一段时间后,发现了另一个代码示例,其中一个人使用带有此符号“&”的 atoi。 所以我这样做了

int octave = atoi(&note[strlen(note) - 1]);

它成功了!但我不明白为什么它与 & 符号一起使用而没有它就不起作用....因为它总是在没有它的情况下工作!有一百万次我给出了一个像 '5' 这样的单字符串,只是使用了 atoi 并且它工作得很好......

请帮帮我,为什么在这种情况下它表现得如此奇怪?

【问题讨论】:

  • C 没有原生的string 类型。那么什么是字符串呢?
  • '5' 不是“字符串”。 "5" 是一个“字符串”。
  • 所以& 的神奇之处不仅仅是一些随机符号,它是 C 的地址操作符,它为您提供指向某物的指针。 C 中的字符串经常使用指向字符的指针来操作。所以要理解这里发生了什么,你将不得不更多地了解 C 中的字符串和指针。你还需要考虑字符和字符串之间的区别:字符是单个字符,而字符串是数组零个或多个字符。
  • 具体来说,notenote + strlen(note) - 1 可以说是一个“字符串”(某种说法); note[strlen(note) - 1] 是单个 char

标签: c char int logic atoi


【解决方案1】:

C 没有原生字符串类型。字符串通常表示为 char 数组或指向 char 的指针。

假设string 只是char * 的类型定义。

如果note 是一个字符数组,note[strlen(note)-1] 只是最后一个字符。由于atoi 需要一个指向 char 的指针(必须以 null 结尾),因此您必须传递 char 的地址而不是值。

将一个 char 数字转换为 int 的任务也可以更容易地解决:

int octave = note[strlen(note) - 1] - '0';

【讨论】:

    【解决方案2】:

    函数atoi 将一个指向字符数组的指针作为输入参数(const char*)。当您调用 note[strlen(note) - 1] 时,这是单个字符 (char),为了使 atoi 工作,您需要提供指针。你可以通过添加& 来做到这一点。然后就可以了,因为在那个单个数字之后有一个空字符 \0 终止字符串 - 因为您的原始字符串是以空字符结尾的。

    但是请注意,这样做不是一个好主意:

    char a = '7';
    int b = atoi(&a);
    

    因为无法确定内存中的下一个字节是什么(在属于a 的字节之后),但该函数无论如何都会尝试读取它,这可能会导致未定义的行为。

    【讨论】:

      【解决方案3】:

      最后一个字符是……嗯,一个字符!不是字符串。因此,通过添加 & 符号,您将其设为指向字符 (char*) 的指针!

      你也可以试试这个代码:

      char a = '5';
      int b = a - '0';
      

      给你5的ASCII码减去0的ASCII码

      【讨论】:

        【解决方案4】:

        manual pagesatoi 的签名是:int atoi(const char *nptr);。因此,您需要传递char 的地址。

        当你这样做时:atoi(note[strlen(note) - 1]) 你传递了char 本身。因此,调用UB

        当您使用& 时,您传递的是函数所期望的——地址。因此,这是可行的。

        【讨论】:

          【解决方案5】:

          atoi 不包括字符串(指向字符的指针),而不是单个字符。

          但是,您永远不应该使用atoi,因为该函数的错误处理能力很差。函数strtol 100% 等效但更安全。

          您需要分两步完成:

          1. 查找字符串中的第一个数字。
          2. 从那里,通过调用 strtol 将其转换为整数。

          1) 可以通过遍历字符串来解决,通过调用 ctype.h 中的 isdigit 检查每个项目是否为数字。同时,检查字符串的结尾,空终止符\0。找到第一个数字后,保存指向该地址的指针。

          2) 通过将保存的指针传递给strtol 来解决,例如result = strtol(pointer, NULL, 10);

          【讨论】:

            猜你喜欢
            • 2014-02-07
            • 2013-08-10
            • 2018-02-10
            • 2010-09-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-18
            相关资源
            最近更新 更多