简体   繁体   English

关于如何在 C 中使用 strchr 的困惑

[英]Confusion on how to use strchr in C

char *strchr( const char *s, int c );

I understand that strchr locates the first occurrence of character c in string s .我知道 strchr 定位字符串s第一次出现的字符c If c is found, a pointer to c in s is returned.如果c被发现,一个指向cs返回。 Otherwise, a NULL pointer is returned.否则,返回NULL指针。

So why does below code outputs num to strlen(string) rather than what its designed to do?那么为什么下面的代码将 num 输出到 strlen(string) 而不是它的设计目的?

num=0;
   while((strchr(string,letter))!=NULL)
   {
      num++;
      string++;
   }

But this code gives correct output但是这段代码给出了正确的输出

num=0;
   while((string=strchr(string,letter))!=NULL)
   {
      num++;
      string++;
   }

I fail to see why assigning the pointer that's returned to another qualified pointer even makes a difference.我不明白为什么将返回的指针分配给另一个合格的指针甚至会有所不同。 I'm only just testing if return value is a NULL pointer or not.我只是在测试返回值是否为 NULL 指针。

  1. string is a pointer. string是一个指针。

  2. In the first example, you just move it right one position, regardless of where (or if!) "letter" was found.在第一个示例中,您只需将其向右移动一个位置,而不管在何处(或是否!)找到“字母”。

  3. In the second example, every time you find a "letter", you:在第二个示例中,每次找到“字母”时,您:

    a) update "string" to point to the letter, then a) 更新 "string" 以指向该字母,然后

    b) update "string" again to point just past the letter. b) 再次更新“string”以指向字母后面。

Let me try to put it in different way,让我试着换一种方式,

strchr

returns a pointer to the located character, or a null pointer if the character does not occur in the string.返回指向所定位字符的指针,如果该字符未出现在字符串中,则返回空指针。

In first part of your snippet return value is not being captured, immediate next position of string from where earlier it was pointing is passed as a argument.在您的代码段返回值的第一部分没有被捕获, string下一个位置从它之前指向的位置作为参数传递。 In short the snippet is counting total number of character till last appearance of letter简而言之,该片段正在计算字符的总数,直到最后一次出现letter

const char* string = "hello"
char letter = 'l'
num=0;
while((strchr(string,letter))!=NULL)
{
    num++;
    string++;
}

Like this,像这样,

            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
              ^
              |
+-------+     |
+string +-----+
+-------+
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                  ^
                  |
+-------+         |
+string +---------+
+-------+

            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                      ^
                      |
+-------+             |
+string +-------------+
+-------+



            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                              ^
                              |
+-------+                     |
+string +---------------------+
+-------+

In second snippet, return value of strchr is captured back into string and immediate next address is passed as argument in next iteration,在第二个代码段中, strchr返回值被捕获回string并在下一次迭代中将立即下一个地址作为参数传递,

const char* string = "hello"
char letter = 'l'
num=0;
while((string = strchr(string,letter))!=NULL)
{
    num++;
    string++;
}

Something like this,像这样的东西,

+-------+     
+string +-----+
+-------+     |
              |
/*input pointer to strchr*/
              |
              v
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                      |
                      |
               /*return pointer from strchr*/
                      |
+-------+             |
+string +<------------+
+-------+     


+-------+                 
+string +-----------------+
+-------+                 |
                          |
            /*input pointer to strchr*/
                          |
                          v
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                          |
                          |
              /*return pointer from strchr*/
+-------+                 |
+string +<----------------+
+-------+     

+-------+                     
+string +---------------------+
+-------+                     |
                              |
                /*input pointer to strchr*/
                              |
                              v
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+

                   /*NULL return from strchr*/
+-------+                     |
+string +<--------------------+
+-------+

First code snippet:第一个代码片段:

So why does below code outputs num to strlen(string) rather than what its designed to do?那么为什么下面的代码将 num 输出到 strlen(string) 而不是它的设计目的?

The output may not be strlen(string) always and will be depend on the input string string and the character letter passed to strchr() .输出可能并不总是strlen(string)并且将取决于输入字符串string和传递给strchr()的字符letter For eg if the input is例如,如果输入是

string = "hello"
letter = 'l'

then the output you will get is 4 which is not equal to the length of string "hello" .那么你将得到的输出是4 ,它不等于字符串"hello"的长度。 If the input is如果输入是

string = "hello"
letter = 'o'

then the output you will get is 5 which is equal to the length of string "hello" .那么你将得到的输出是5 ,它等于字符串"hello"的长度。 If the input is如果输入是

string = "hello"
letter = 'x'

then the output you will get is 0 .那么你将得到的输出是0
The output is actually depends on the position of last occurrence of the character letter in the input string.输出实际上取决于输入字符串中字符letter最后一次出现的位置。

Reason is that there is only one statement which is modifying the position of string pointer and that statement is原因是只有一个语句在修改string指针的位置,该语句是

      string++;

It is working in this way -它以这种方式工作 -
If the character present in the string , the strchr() will return a not null value till the time the input string pointer point to a character on or before the last occurrence of character letter in the string.如果string存在string ,则strchr()将返回一个非空值,直到输入string指针指向string最后一次出现字符letter或之前的字符为止。 Once string pointer point to one character after the last occurrence of letter character in the string, the strchr() will return NULL and loop exits and num will be equal to position of the last occurrence of letter character in the string.一旦string指针指向string最后一次出现letter字符后的一个字符, strchr()将返回NULL并退出循环, num将等于字符串中最后一次出现letter字符的位置。 So, you will get the output within the range from 0 to strlen(string) and not strlen(string) always.因此,您将始终获得从0strlen(string)而不是strlen(string)范围内的输出。

string = "hello", letter = 'e', num = 0
strchr(string, letter) will return not null as 'e' present in input string
num++; string++;

string = "ello", letter = 'e', num = 1
strchr(string, letter) will return not null as 'e' present in input string
num++; string++;

string = "llo", letter = 'e', num = 2
strchr(string, letter) will return null as it does not find 'e' in input string and loop exits

Output will be 2

Second code snippet:第二个代码片段:

But this code gives correct output但是这段代码给出了正确的输出

Yes, the reason is the strchr() returned pointer is assigned to string pointer.是的,原因是strchr()返回的指针被分配给string指针。 Take the same example as above, assume the input is拿上面同样的例子,假设输入是

string = "hello"
letter = 'l'

strchr(string, letter) will return the pointer to first occurrence of character l and it is assigned to pointer string . strchr(string, letter)将返回指向第一次出现字符l的指针,并将其分配给指针string So, now the string pointer pointing first occurrence of l .所以,现在字符串指针指向第一次出现的l Which means, now the string is这意味着,现在string

string = "llo"

and in loop body you are doing在循环体中你正在做

string++;

which will make the string pointer point to next character to the character returned by strchr() .这将使字符串指针指向strchr()返回的字符的下一个字符。 Now the string is现在string

string = "lo"
letter = `l`

and strchr(string, letter) will return the pointer to character which the string is pointing to currently as it is matching to character letter .strchr(string, letter)将返回指向string当前指向的string的指针,因为它与字符letter匹配。 Due to string++ in the loop body, now the string will point to next character由于循环体中的string++ ,现在字符串将指向下一个字符

string = "o"
letter = `l`

and strchr(string, letter) will return NULL and loop will exit.并且strchr(string, letter)将返回NULL并且循环将退出。 num is incremented as many times as the character letter found in string . num增加的次数与在string找到的字符letter一样多。 Hence the second snippet is giving correct output.因此,第二个片段给出了正确的输出。

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

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