在 C 中将 "char" 转换为 "int" 的逻辑
LOGIC of Converting a "char" into an "int" in C
各位!
请帮我理解以下问题...
所以我将有一个字符串类型的音符输入,看起来像 "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);
但是它给了我一个错误"error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Werror,-Wint-conversion]"
然后我尝试从函数中去掉数学运算,然后这样做:
int extnum = strlen(note) - 1;
int octave = atoi(note[extnum]);
它也没有用。所以我研究了 atoi 函数,但我不明白...
- ATOI 需要一个字符串 (CHECK)
- 将其转换为整数,而不是 ASCII 含义(检查)
- atoi 函数库(检查)
基本上我在问什么"take n-th character of that string and make it an int"。
在谷歌搜索一段时间后,我发现了另一个代码示例,其中一个人使用带有此符号“&”的 atoi。 所以我这样做了:
int octave = atoi(¬e[strlen(note) - 1]);
成功了!但我不明白为什么它与 & 符号一起工作而没有它就不能工作......因为没有它它总是有效!有一百万次我给出了一个像“5”这样的单字符字符串,只是使用了 atoi 并且它完美地工作......
请帮帮我,为什么在这种情况下它表现得如此奇怪?
函数atoi
将指向字符数组的指针作为输入参数(const char*
)。当您调用 note[strlen(note) - 1]
时,这是单个字符 (char
),为了使 atoi
工作,您需要提供指针。您可以通过添加 &
来实现。这样就可以了,因为在那个单个数字之后有一个终止字符串的空字符 [=17=]
- 因为您的原始字符串是以空值终止的。
但是请注意,这样做并不是一个好主意:
char a = '7';
int b = atoi(&a);
因为无法确定内存中的下一个字节是什么(跟在属于 a
的字节之后),但是该函数无论如何都会尝试读取它,这可能会导致未定义的行为.
最后一个角色是……好角色!不是字符串。因此,通过添加 &
符号,您使其成为指向字符 (char*
)!
的指针
您也可以试试这个代码:
char a = '5';
int b = a - '0';
给你 5
的 ASCII 码减去 0
的 ASCII 码
C 没有原生字符串类型。字符串通常表示为 char 数组或指向 char 的指针。
假设 string
只是 char *
的类型定义。
如果 note
是一个字符数组,note[strlen(note)-1]
只是最后一个字符。由于 atoi
需要指向 char 的指针(必须以 null 结尾),因此您必须传递 char 的地址而不是值。
将一个 char 数字转换为 int 的任务也可以更容易地解决:
int octave = note[strlen(note) - 1] - '0';
来自manual pages,atoi
的签名是:int atoi(const char *nptr);
。所以,你需要传递一个char
的地址。
当您这样做时:atoi(note[strlen(note) - 1])
您传递了 char
本身。因此,调用 UB.
当您使用 &
时,您传递的是函数所期望的 - 地址。因此,这有效。
atoi
除了字符串(指向字符的指针),而不是单个字符。
但是,您永远不应使用 atoi
,因为该函数的错误处理很糟糕。函数 strtol
100% 等效但更安全。
您需要分两步完成:
- 找到字符串中的第一个数字。
- 从那里,通过调用
strtol
. 将其转换为整数
1) 可以通过遍历字符串来解决,通过从 ctype.h 调用 isdigit
检查每个项目是否是数字。同时,检查字符串的结尾,空终止符 [=15=]
。当您找到第一个数字时,保存指向该地址的指针。
2)通过将保存的指针传给strtol
来解决,比如result = strtol(pointer, NULL, 10);
.
各位!
请帮我理解以下问题... 所以我将有一个字符串类型的音符输入,看起来像 "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);
但是它给了我一个错误"error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Werror,-Wint-conversion]"
然后我尝试从函数中去掉数学运算,然后这样做:
int extnum = strlen(note) - 1;
int octave = atoi(note[extnum]);
它也没有用。所以我研究了 atoi 函数,但我不明白...
- ATOI 需要一个字符串 (CHECK)
- 将其转换为整数,而不是 ASCII 含义(检查)
- atoi 函数库(检查)
基本上我在问什么"take n-th character of that string and make it an int"。
在谷歌搜索一段时间后,我发现了另一个代码示例,其中一个人使用带有此符号“&”的 atoi。 所以我这样做了:
int octave = atoi(¬e[strlen(note) - 1]);
成功了!但我不明白为什么它与 & 符号一起工作而没有它就不能工作......因为没有它它总是有效!有一百万次我给出了一个像“5”这样的单字符字符串,只是使用了 atoi 并且它完美地工作......
请帮帮我,为什么在这种情况下它表现得如此奇怪?
函数atoi
将指向字符数组的指针作为输入参数(const char*
)。当您调用 note[strlen(note) - 1]
时,这是单个字符 (char
),为了使 atoi
工作,您需要提供指针。您可以通过添加 &
来实现。这样就可以了,因为在那个单个数字之后有一个终止字符串的空字符 [=17=]
- 因为您的原始字符串是以空值终止的。
但是请注意,这样做并不是一个好主意:
char a = '7';
int b = atoi(&a);
因为无法确定内存中的下一个字节是什么(跟在属于 a
的字节之后),但是该函数无论如何都会尝试读取它,这可能会导致未定义的行为.
最后一个角色是……好角色!不是字符串。因此,通过添加 &
符号,您使其成为指向字符 (char*
)!
您也可以试试这个代码:
char a = '5';
int b = a - '0';
给你 5
的 ASCII 码减去 0
C 没有原生字符串类型。字符串通常表示为 char 数组或指向 char 的指针。
假设 string
只是 char *
的类型定义。
如果 note
是一个字符数组,note[strlen(note)-1]
只是最后一个字符。由于 atoi
需要指向 char 的指针(必须以 null 结尾),因此您必须传递 char 的地址而不是值。
将一个 char 数字转换为 int 的任务也可以更容易地解决:
int octave = note[strlen(note) - 1] - '0';
来自manual pages,atoi
的签名是:int atoi(const char *nptr);
。所以,你需要传递一个char
的地址。
当您这样做时:atoi(note[strlen(note) - 1])
您传递了 char
本身。因此,调用 UB.
当您使用 &
时,您传递的是函数所期望的 - 地址。因此,这有效。
atoi
除了字符串(指向字符的指针),而不是单个字符。
但是,您永远不应使用 atoi
,因为该函数的错误处理很糟糕。函数 strtol
100% 等效但更安全。
您需要分两步完成:
- 找到字符串中的第一个数字。
- 从那里,通过调用
strtol
. 将其转换为整数
1) 可以通过遍历字符串来解决,通过从 ctype.h 调用 isdigit
检查每个项目是否是数字。同时,检查字符串的结尾,空终止符 [=15=]
。当您找到第一个数字时,保存指向该地址的指针。
2)通过将保存的指针传给strtol
来解决,比如result = strtol(pointer, NULL, 10);
.