简体   繁体   English

C中的strlen函数

[英]strlen function in c

This might sound a bit dumb but am confused. 这听起来可能有些愚蠢,但却感到困惑。 I know the strlen() would return the size of the character array in c. 我知道strlen()会返回c中字符数组的大小。 But there is something different going on with pointers to character. 但是指向字符的指针发生了一些变化。 This is my code: 这是我的代码:

void xyz(char *number)
{
    int i = 0;
    int length = strlen(number) - 2;
    while(i <= length)
    {
        printf("Number[]: %c",number[i]);
        i++;
    }
}

This prints the entire number I enter (Eg: 12345) but if I remove the -2 the result is not the same. 这会打印出我输入的完整数字(例如:12345),但是如果我删除了-2,结果将是不同的。 Could anyone tell me what am I missing? 谁能告诉我我想念什么?

There's a good chance that you're doing this to a string that you have obtained with fgets or a similar input function. 您很有可能会对使用fgets或类似输入函数获得的字符串执行此操作。 In that case, it may well have the newline at the end still. 在这种情况下,很可能换行符仍在末尾。

If you change your code temporarily to: 如果您将代码临时更改为:

void xyz (char *number) {
    int i = 0, length = strlen (number);
    while (i < length)
        printf ("Number[%d]: %c (%d)", i, number[i], number[i]);
        i++;
    }
}

that should also show the numeric codes for all characters. 还应该显示所有字符的数字代码。

The problem with encoding something like that - 2 in your function is that it will not work with: 在您的函数中编码类似这样的东西- 2的问题是它不适用于:

xyz ("123");

since it will stop early, printing out only 12 . 因为它将提前停止,所以只打印12 The caller should be calling with valid data, meaning that it should adjust the value to be a numeric string before calling. 调用方应使用有效数据进行调用,这意味着在调用前应将其值调整为数字字符串。


You can see this happening in the following program: 您可以在以下程序中看到这种情况:

#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;
}

The (annoted) output of this, if you enter 98765 , is: 如果输入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)
===

If you're looking for a robust user input function that gets around this problem (and avoids dangerous things like unbounded scanf("%s") and gets ), I have one elsewhere on SO (right HERE , in fact) drawn from my arsenal. 如果您正在寻找可以解决此问题的强大的用户输入函数(并且避免了诸如unbounded scanf("%s")这样的危险事件并gets )的信息,那么我会在SO的其他地方(实际上是在这里 )兵工厂。

Check if this works for you -- 检查是否适合您-

void xyz(char *number)
{
    int length = strlen(number);

    while(i < length)
    {
        printf("Number[]: %c",number[i]);
        i++;
    }
}

and this function, if invoked as 和此函数(如果调用为

xyz("1234");

should print out: 应该打印出来:

Number[]: 1
Number[]: 2
Number[]: 3
Number[]: 4

Is that what you really wanted ? 那是您真正想要的吗? If so, then let me point 2 mistakes. 如果是这样,那么让我指出2个错误。

1) "i" is not initialized. 1)“ i”未初始化。 It is more a question of good practise. 这更多是一个良好实践的问题。 Explicitly initialize your loop control variable (to zero in this case), just don't assume it to be set. 显式初始化循环控制变量(在这种情况下为零),只是不要假定已对其进行设置。 2) your while loop condition with "<=" runs 1 extra cycle that it should. 2)使用“ <=”的while循环条件应该多运行1个周期。

Remember that arrays start from index '0' (zero), and an array of size 10, has valid index from 0 to 9, and C lang uses null character ('\\0'), to terminate a string. 请记住,数组从索引'0'(零)开始,大小为10的数组具有从0到9的有效索引,并且C lang使用空字符('\\ 0')来终止字符串。 So, your "1234" is actually stored as:- 因此,您的“ 1234”实际上存储为:

string[0] = '1' string[1] = '2' string[2] = '3' string[3] = '4' string[4] = '\\0' (<= NULL) 字符串[0] ='1'字符串[1] ='2'字符串[2] ='3'字符串[3] ='4'字符串[4] ='\\ 0'(<= NULL)

so if your loop-counter (control variable) i=0 at beginning of loop, for first iteration, you pick string[0], and for 2nd iteration (when i=1) you pick string[1]... and this way, the loop should run only 4 times, ie when i==4 (ie loopcounter < string-length), you must stop & exit loop. 因此,如果循环计数器(控制变量)在循环开始时i = 0,则对于第一次迭代,您选择字符串[0],对于第二次迭代(当i = 1时),您选择字符串[1] ...这样,循环应该只运行4次,即当i == 4(即loopcounter <字符串长度)时,您必须停止并退出循环。

Hope this clears up your doubt and help. 希望这能消除您的疑问和帮助。 If so, please don't forget to accept the answer. 如果是这样,请不要忘记接受答案。

I did this and received an output like this: 我这样做了,并收到了这样的输出:

strlen(number)-2 removes the last null and the last character, which contains 4. strlen(number)-2删除最后一个null和最后一个包含4的字符。

Output: 输出:

 Number[]: 1 Number[]: 2 Number[]: 3 

Code: 码:

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++;
    }
}

It works, and you have to initialize i . 它有效,并且您必须初始化i

strlen() returns the length of the string, but C arrays, and thus strings, are zero indexed. strlen()返回字符串的长度,但是C数组(因此字符串)的索引为零。 So you want to increment until you reach strlen() - 1 . 因此,您要增加直到达到strlen() - 1 You can do that either by subtracting one from your length and using a less-than-or-equal test - <= - in your while loop or you can just use strlen() and continue your loop as long as your counter is strictly less than your length. 您可以通过从长度中减去一个并使用小于或等于测试- <= -在while循环中执行此操作,也可以只使用strlen()并继续循环,只要您的计数器严格小于比你的长度。

Possibly sources of error: 可能的错误来源:

  1. If you don't initialize i , odds are the value it gets from whatever was previously at that memory location will be well above length. 如果不初始化i ,则赔率就是它从该内存位置先前所获得的值将大大超过长度。 So your while condition will fail on the first execution. 因此,您的while条件将在第一次执行时失败。
  2. If go past the end of the string, you will see a NULL character - '\\0' - at the end of the string, and random garbage past that. 如果超过字符串的末尾,您将在字符串的末尾看到一个NULL字符- '\\0' ,并在该字符串之后进行随机垃圾回收。

My guess is you're using fgets to read in some input. 我的猜测是您正在使用fgets读取某些输入。 If that's the case, when you enter "12345" and hit enter, your buffer will look like this: 在这种情况下,当您输入“ 12345”并按Enter键时,您的缓冲区将如下所示:

{'1', '2', '3', '4', '5', '\\n', '\\0'} {'1','2','3','4','5','\\ n','\\ 0'}

As you can see there's 2 characters we don't want. 如您所见,我们不需要2个字符。 So what we can do for a start is chop off the newline char , '\\n' from the end of your buffer. 因此,我们可以做的就是从缓冲区末尾截断换行符char '\\n'

So pretend this is how we read in the input: 因此,假设这是我们在输入中读取的方式:

int main(void)
{
   char buff[20];
   fgets(buff, 20, stdin);

   buff[strlen(buff) - 1] = '\0'; /* remove the '\n' */
   xyz(buff);
}

Now that annoying newline character won't be there and what will look like empty output for the last iteration of the loop will be gone. 现在,烦人的换行符将不再存在,而看起来像空的循环最后一次迭代输出将消失。 Now for xyz : 现在为xyz

void xyz(char *number)
{
   int i, length = strlen(number);
   for (i = 0; i < length; i++)
      printf("Number[%d]: %c", i, number[i]);
}

Note that we're now not subtracting anything from the length. 请注意,我们现在从长度中减去任何东西。 This is for 2 reasons: the first that I mentioned above about the newline, and secondly because the condition is now < length as opposed to <= length (which I mentioned in the comment above). 这有两个原因:第一个是我在上面提到的换行符,第二个是因为条件现在是< length ,而不是<= length (我在上面的评论中提到过)。 <= length means that we would be reading 1 past the end of the string (the '\\0' character), since the first index is number[0] and the last number[length - 1] . <= length表示我们将在字符串末尾(“ \\ 0”字符)之后读取1,因为第一个索引是number[0] ,最后一个number[length - 1]

You would actually have to do: 您实际上必须要做的是:

int length = strlen(number) - 1;

To get the correct output. 获得正确的输出。

In addition, you have to remember that you are passing a character array to your xyz function. 此外,您还必须记住,您正在将字符数组传递给xyz函数。 So if you did the following: 因此,如果您执行以下操作:

xyz("12345")

your length would be 5 bytes. 您的长度为5个字节。 In your while loop, your for number[i] index actually starts at 0, not 1, thus you need to subtract 1 to get the correct result, hence you use int length = strlen(number) - 1 . 在while循环中,for number[i]索引实际上从0开始,而不是1,因此您需要减去1以获得正确的结果,因此使用int length = strlen(number) - 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM