这可能听起来有点愚蠢但很困惑。 我知道strlen()会返回c中字符数组的大小。但是对于角色的指针有一些不同的东西。 这是我的代码:
void xyz(char *number)
{
int i = 0;
int length = strlen(number) - 2;
while(i <= length)
{
printf("Number[]: %c",number[i]);
i++;
}
}
这将打印我输入的整个数字(例如:12345),但如果我删除-2,则结果不一样。 谁能告诉我我错过了什么?
答案 0 :(得分:6)
您很有可能对使用fgets
或类似输入函数获得的字符串执行此操作。在这种情况下,它最终可能会有换行符。
如果您暂时将代码更改为:
void xyz (char *number) {
int i = 0, length = strlen (number);
while (i < length)
printf ("Number[%d]: %c (%d)", i, number[i], number[i]);
i++;
}
}
还应显示所有字符的数字代码。
在您的函数中对- 2
之类的编码进行编码的问题在于它无法使用:
xyz ("123");
因为它会提前停止,所以只打印12
。 调用者应该使用有效数据进行调用,这意味着它应该在调用之前将值调整为数字字符串。
您可以在以下程序中看到这种情况:
#include <stdio.h>
#include <string.h>
void xyz (char *number) {
int i = 0, length = strlen(number) - 2;
while(i <= length)
{
printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
i++;
}
puts ("===");
}
void xyz2 (char *number) {
int i = 0, length = strlen(number);
while(i < length)
{
printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
i++;
}
puts ("===");
}
int main (void) {
char buff[100];
printf ("Enter number: ");
fgets (buff, sizeof (buff), stdin);
xyz (buff);
xyz ("12345");
xyz2 (buff);
xyz2 ("12345");
return 0;
}
如果您输入98765
,此输出(带注释)为:
Enter number: 98765
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55) # Your adjustment works here because of the newline.
Number[3]: 6 (54)
Number[4]: 5 (53)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51) # But not here, since it skips last character.
Number[3]: 4 (52)
===
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55) # Here you can see the newline (code 10).
Number[3]: 6 (54)
Number[4]: 5 (53)
Number[5]:
(10)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51) # And proper numeric strings work okay.
Number[3]: 4 (52)
Number[4]: 5 (53)
===
如果你正在寻找一个可以解决这个问题的强大的用户输入功能(并且避免了诸如无限scanf("%s")
和gets
之类的危险事情),我在其他地方也有一个(右{{3事实上)来自我的武器库。
答案 1 :(得分:1)
检查这是否适合您 -
void xyz(char *number)
{
int length = strlen(number);
while(i < length)
{
printf("Number[]: %c",number[i]);
i++;
}
}
和此函数,如果调用为
xyz("1234");
应打印出来:
Number[]: 1
Number[]: 2
Number[]: 3
Number[]: 4
那是你真正想要的吗?如果是这样,那么让我指出2个错误。
1)“i”未初始化。这更是一个良好做法的问题。显式初始化循环控制变量(在这种情况下为零),只是不要假设它被设置。 2)你的while循环条件“&lt; =”运行1个额外的循环。
请记住,数组从索引'0'(零)开始,大小为10的数组具有从0到9的有效索引,而C lang使用空字符('\ 0')来终止字符串。所以,你的“1234”实际上存储为: -
string [0] ='1' string [1] ='2' string [2] ='3' string [3] ='4' string [4] ='\ 0'(&lt; = NULL)
所以如果你的循环计数器(控制变量)在循环开始时i = 0,对于第一次迭代,你选择字符串[0],对于第二次迭代(当i = 1时)你选择字符串[1] ..这样,循环应该只运行4次,即当i == 4(即loopcounter&lt; string-length)时,你必须停止&amp;退出循环。
希望这能清除你的怀疑和帮助。如果是这样,请不要忘记接受答案。
答案 2 :(得分:1)
我这样做并收到了这样的输出:
strlen(number)-2
删除最后一个空值和最后一个包含4的字符。
输出:
Number[]: 1 Number[]: 2 Number[]: 3
代码:
int main()
{
xyz("1234");
}
void xyz(char *number)
{
int i=0;
int length = strlen(number) - 2;
while(i <= length)
{
printf("\nNumber[]: %c",number[i]);
i++;
}
}
它有效,您必须初始化i
。
答案 3 :(得分:0)
strlen()
返回字符串的长度,但C数组和字符串是零索引。所以你想增加直到达到strlen() - 1
。您可以通过从长度中减去一个并使用小于或等于的测试<=
- 在您的while循环中执行此操作,或者只需使用strlen()
并继续循环,只要你的柜台严格
可能是错误来源:
i
,则赔率是从之前在该记忆位置的任何东西得到的值远远超过长度。因此,您的while条件将在第一次执行时失败。'\0'
,并且随后会看到随机垃圾。 答案 4 :(得分:0)
我的猜测是你正在使用fgets
读取一些输入。如果是这种情况,当您输入“12345”并按Enter键时,您的缓冲区将如下所示:
{'1','2','3','4','5','\ n','\ 0'}
正如您所看到的,我们不想要 2 字符。因此,我们可以开始做的就是从缓冲区末尾删除换行符char
,'\n'
。
假设这是我们在输入中读到的内容:
int main(void)
{
char buff[20];
fgets(buff, 20, stdin);
buff[strlen(buff) - 1] = '\0'; /* remove the '\n' */
xyz(buff);
}
现在恼人的换行符将不存在,并且循环的最后一次迭代的空输出将会消失。现在是xyz
:
void xyz(char *number)
{
int i, length = strlen(number);
for (i = 0; i < length; i++)
printf("Number[%d]: %c", i, number[i]);
}
请注意,我们现在不从长度中减去任何内容。这有两个原因:我上面提到的关于换行的第一个原因,其次是因为条件现在是< length
而不是<= length
(我在上面的评论中提到过)。 <= length
表示我们将在字符串末尾('\ 0'字符)后读取1,因为第一个索引是number[0]
,而最后一个number[length - 1]
。
答案 5 :(得分:0)
你实际上必须这样做:
int length = strlen(number) - 1;
获得正确的输出。
此外,您必须记住您正在将字符数组传递给xyz函数。所以如果你做了以下事情:
xyz("12345")
你的长度是5个字节。在while循环中,for number[i]
索引实际上从0开始,而不是1,因此您需要减去1以获得正确的结果,因此您使用int length = strlen(number) - 1
。