[英]LOGIC of Converting a “char” into an “int” in C
everyone! 大家!
please help me understand the following problem... So i will have a STRING-type input of a note, looks like "A5" or "G#2" or "Cb4" etc. And i need to extract an octave index, which is the last digit "5" or "2" or "4"... And after exctraction i need it as an int-type. 请帮助我理解以下问题...因此,我将具有注释的STRING类型输入,看起来像“ A5”或“ G#2”或“ Cb4”等。并且我需要提取一个八度音阶索引,是最后一个数字“ 5”或“ 2”或“ 4” ...提取后,我需要将其作为整数类型。
So I did this: 所以我这样做:
string note = get_string("Input: ");
int octave = atoi(note[strlen(note) - 1]);
printf("your octave is %i \n", octave);
But it gave me an error "error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Werror,-Wint-conversion]" 但这给了我一个错误“错误:将指针'char'传递给'const char *'类型的参数的指针转换的不兼容整数;使用&[-Werror,-Wint-conversion]来获取地址”
Then I tryied to throug away the math from the function, and did this: 然后,我尝试摆脱函数中的数学运算,并执行以下操作:
int extnum = strlen(note) - 1;
int octave = atoi(note[extnum]);
It didn't work as well. 效果也不佳。 So i did my reserch on atoi function and i don't get it...
所以我对atoi函数进行了研究,但我不明白...
What I am doing in basically asking "take n-th character of that string and make it an int". 我在做的主要是询问“采用该字符串的第n个字符并将其设置为int”。
After googling for some time a found an other code example where a guy uses atoi with this symbol '&'. 谷歌搜索一段时间后,找到了另一个代码示例,其中一个人使用atoi并带有“&”符号。 So i did this :
所以我做到了 :
int octave = atoi(¬e[strlen(note) - 1]);
And IT WORKED! 和它的工作! But I can't understand WHY it worked with the & symbol and didnt work without it....Cause it always worked without it!
但是我不明白为什么它与&符号一起工作,而没有它却无法工作....因为它总是在没有它的情况下工作! There was a million times i was giving a single-character string like '5' or so ond just used atoi and it worked perfectly...
我曾经给过一百万次输入像atooi这样的单字符字符串'5'或类似的命令,并且效果很好。
Plesase help me, why in this case it acts so weird? 请帮我,为什么在这种情况下它表现得如此怪异?
C does not have a native string type. C没有本地字符串类型。 Strings are usually represented as char array or a pointer to char.
字符串通常表示为char数组或char指针。
Assuming that string
is just a typedef to char *
. 假设该
string
只是char *
的typedef。
if note
is an array of chars, note[strlen(note)-1]
is just the last character. 如果
note
是一个字符数组,则note[strlen(note)-1]
只是最后一个字符。 Since atoi
expects a pointer to char (which has to be null-terminated) you have to pass the address of the char and not the value. 由于
atoi
需要一个指向char的指针(必须为null终止),因此您必须传递char的地址而不是值。
The task to convert one char digit to int could also be solved easier: 将一个字符转换为整数的任务也可以更容易地解决:
int octave = note[strlen(note) - 1] - '0';
The function atoi
takes a pointer to a character array as the input parameter ( const char*
). 函数
atoi
将指向字符数组的指针作为输入参数( const char*
)。 When you call note[strlen(note) - 1]
this is a single character ( char
), in order to make atoi
work you need to provide the pointer. 调用
note[strlen(note) - 1]
这是一个字符( char
),为了使atoi
工作,您需要提供指针。 You do that by adding &
as you've done. 您可以通过添加
&
完成此操作。 This then works, because right after that single digit there is a null character \\0
that terminates the string - because your original string was null-terminated. 这样就可以了,因为在该个数字之后有一个空字符
\\0
终止了该字符串-因为原始字符串以空字符结尾。
Note however that doing something like this would not be a good idea: 但是请注意,这样做不是一个好主意:
char a = '7';
int b = atoi(&a);
as there is no way to be sure what the next byte in memory is (following the byte that belongs to a
), but the function will try to read it anyway, which can lead to undefined behaviour. 因为无法确定内存中的下一个字节是什么(跟在属于
a
的字节之后),但是该函数仍将尝试读取该字节,这可能导致未定义的行为。
The last character is... well a character! 最后一个角色是……一个角色! not a string.
不是字符串。 So by adding the
&
sign, you made it a pointer to character ( char*
)! 因此,通过添加
&
符号,可以使其成为指向字符( char*
)的指针!
You can also try this code: 您也可以尝试以下代码:
char a = '5';
int b = a - '0';
Gives you ASCII code of 5
minus ASCII code of 0
给您
5
ASCII码减去0
ASCII码
From the manual pages , the signature of atoi
is: int atoi(const char *nptr);
在手册页上 ,
atoi
的签名为: int atoi(const char *nptr);
. 。 So, you need to pass the address of a
char
. 所以,你需要传递的地址
char
。
When you do this: atoi(note[strlen(note) - 1])
you pass the char
itself. 执行此操作时:
atoi(note[strlen(note) - 1])
您将传递char
本身。 Thus, invoking UB . 因此,调用UB 。
When you use the &
, you are passing what the function expects - the address. 当使用
&
,您将传递函数期望的地址。 Hence, that works. 因此,这可行。
atoi
excepts a string (a pointer to character), not a single character. atoi
除了字符串(指向字符的指针)以外,而不是单个字符。
However, you should never use atoi
since that function has bad error handling. 但是,您永远不要使用
atoi
因为该函数具有错误的错误处理。 The function strtol
is 100% equivalent but safer. 功能
strtol
是100%等效但更安全。
You need to do this in two steps: 您需要分两步执行此操作:
strtol
. strtol
将其转换为整数。 1) can is solved by looping through the string, checking if every item is a digit by calling isdigit
from ctype.h. 1)可以通过遍历字符串来解决,可以通过从ctype.h调用
isdigit
来检查每个项目是否都是数字。 Simultaneously, check for the end of the string, the null terminator \\0
. 同时,检查字符串的结尾,即空终止符
\\0
。 When you find the first digit, save a pointer to that address. 当找到第一个数字时,保存指向该地址的指针。
2) is solved by passing the saved pointer to strtol
, such as result = strtol(pointer, NULL, 10);
2)通过将保存的指针传递给
strtol
来解决,例如result = strtol(pointer, NULL, 10);
. 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.