所有人!
请帮助我了解以下问题... 因此,我将具有音符的STRING类型输入,看起来像“ 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]来获取地址” < / strong>
然后,我尝试从函数中排除数学运算,并执行以下操作:
int extnum = strlen(note) - 1;
int octave = atoi(note[extnum]);
效果不佳。所以我对atoi函数进行了研究,但我不明白...
我基本上是在问“取该字符串的第n个字符并将其设为整数”。
谷歌搜索一段时间后,发现另一个代码示例,其中一个人使用atoi并带有符号“&”。 所以我做到了:
int octave = atoi(¬e[strlen(note) - 1]);
而且成功了!但是我不明白为什么它与&符号一起工作,而没有它却无法工作....因为它总是在没有它的情况下工作!一百万次,我给单字符字符串(如atoi)加上了“ 5”等,并且效果很好。
请帮助我,为什么在这种情况下它表现得如此怪异?
答案 0 :(得分:3)
C没有本机字符串类型。字符串通常表示为char数组或指向char的指针。
假设string
只是char *
的typedef。
如果note
是一个字符数组,则note[strlen(note)-1]
只是最后一个字符。由于atoi
需要一个指向char的指针(必须为null终止),因此您必须传递char的地址而不是值。
将一个字符转换为整数的任务也可以更轻松地解决:
int octave = note[strlen(note) - 1] - '0';
答案 1 :(得分:0)
函数atoi
将指向字符数组的指针作为输入参数(const char*
)。调用note[strlen(note) - 1]
时,这是一个字符(char
),为了使atoi
正常工作,您需要提供指针。您可以通过添加&
来完成此操作。这样就可以了,因为在该个数字之后有一个空字符\0
来终止该字符串-因为您的原始字符串以空字符结尾。
但是请注意,这样做不是一个好主意:
char a = '7';
int b = atoi(&a);
,因为无法确定内存中的下一个字节是什么(跟在属于a
的字节之后),但是该函数将始终尝试读取它,这可能导致未定义的行为。
答案 2 :(得分:0)
最后一个角色是……一个角色!不是字符串。因此,通过添加&
符号,可以使其成为指向字符(char*
)的指针!
您也可以尝试以下代码:
char a = '5';
int b = a - '0';
为您提供5
的ASCII码减去0
的ASCII码
答案 3 :(得分:0)
在manual pages中,atoi
的签名为:int atoi(const char *nptr);
。因此,您需要传递char
的地址。
执行此操作时:atoi(note[strlen(note) - 1])
会传递char
本身。因此,调用UB。
使用&
时,您传递的是函数期望的地址-地址。因此,那行得通。
答案 4 :(得分:0)
atoi
,但字符串(指向字符的指针)除外,而不是单个字符。
但是,您永远不要使用atoi
,因为该函数具有错误的错误处理。函数strtol
是100%等效的,但更安全。
您需要分两个步骤进行操作:
strtol
将其转换为整数。 1)can可以通过遍历字符串来解决,可以通过从ctype.h调用isdigit
来检查每个项目是否都是数字。同时,检查字符串的结尾,即空终止符\0
。找到第一个数字后,保存指向该地址的指针。
2)通过将保存的指针传递到strtol
,例如result = strtol(pointer, NULL, 10);
来解决。