【问题标题】:Confusion on how to use strchr in C关于如何在 C 中使用 strchr 的困惑
【发布时间】:2020-05-11 08:10:15
【问题描述】:
char *strchr( const char *s, int c );

我知道 strchr 在字符串 s 中定位字符 c 的第一次出现。如果找到c,则返回指向s 中的c 的指针。否则,将返回 NULL 指针。

那么为什么下面的代码输出 num 到 strlen(string) 而不是它的设计目的呢?

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

但是这段代码给出了正确的输出

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

我不明白为什么将返回的指针分配给另一个合格的指针甚至会产生影响。我只是测试返回值是否为 NULL 指针。

【问题讨论】:

  • 关于strchr( const char *s, int c ) 的其他说明:搜索到的字符串 包含null 字符,因此strchr(some_strings, 0) 永远不会返回NULL。搜索就像 *sch 转换为 unsigned char 一样完成。
  • 这就是我的看法:返回指向第一个\0 的指针,即在字符串的末尾。由于此时(string=strchr(string, letter))!=NULL 为真,string++ 将出现,并且字符串将指向超出其分配的内存。这是否会导致某种奇怪的行为永远不会返回NULL?还是我在这里走错了路?
  • Leon, letter 的值是 null 字符 是不太可能的情况。但如果代码确实需要处理这个问题,可以使用while((string=strchr(string,letter))!=NULL && *string)

标签: c strchr


【解决方案1】:
  1. string 是一个指针。

  2. 在第一个示例中,您只需将其向右移动一个位置,无论在何处(或是否!)找到“字母”。

  3. 在第二个例子中,每次你找到一个“字母”,你:

    a) 更新 "string" 以指向该字母,然后

    b) 再次更新“字符串”以指向刚刚过去的字母。

【讨论】:

    【解决方案2】:

    让我试着换一种方式,

    strchr

    返回一个指向定位字符的指针,如果该字符没有出现在字符串中,则返回一个空指针。

    在你的 sn-p 返回值的第一部分没有被捕获,string 的下一个位置从它之前指向的位置作为参数传递。 简而言之,sn-p 正在计算直到最后一次出现 letter 的字符总数

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

    这样,

                +---+---+---+---+---+----+
                |'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 +---------------------+
    +-------+
    

    在第二个 sn-p 中,strchr 的返回值被捕获回string,并在下一次迭代中将下一个地址作为参数传递,

    const char* string = "hello"
    char letter = 'l'
    num=0;
    while((string = strchr(string,letter))!=NULL)
    {
        num++;
        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,|
                +---+---+---+---+---+----+
                              |
                              |
                  /*return pointer from strchr*/
    +-------+                 |
    +string +<----------------+
    +-------+     
    
    +-------+                     
    +string +---------------------+
    +-------+                     |
                                  |
                    /*input pointer to strchr*/
                                  |
                                  v
                +---+---+---+---+---+----+
                |'h'|'e'|'l'|'l'|'o'|'/0,|
                +---+---+---+---+---+----+
    
                       /*NULL return from strchr*/
    +-------+                     |
    +string +<--------------------+
    +-------+
    

    【讨论】:

    • 对于视觉效果,帮助我立即理解它+1。
    【解决方案3】:

    第一个代码sn-p:

    那么为什么下面的代码输出 num 到 strlen(string) 而不是它的设计目的呢?

    输出可能并非总是strlen(string),而是取决于输入字符串string 和传递给strchr() 的字符letter。例如如果输入是

    string = "hello"
    letter = 'l'
    

    那么你将得到的输出是4,它不等于字符串"hello"的长度。如果输入是

    string = "hello"
    letter = 'o'
    

    那么你将得到的输出是5,它等于字符串"hello"的长度。如果输入是

    string = "hello"
    letter = 'x'
    

    那么你将得到的输出是0
    输出实际上取决于字符 letter 在输入字符串中最后出现的位置。

    原因是只有一条语句在修改string指针的位置,该语句是

          string++;
    

    它以这种方式工作 -
    如果字符存在于string 中,则strchr() 将返回非空值,直到输入string 指针指向字符串中最后一次出现字符letter 上或之前的字符。一旦string 指针指向字符串中最后一次出现letter 字符后的一个字符,strchr() 将返回NULL 并退出循环,num 将等于最后一次出现@987654345 的位置@ 字符串中的字符。因此,您将获得从 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
    

    二码sn-p:

    但是这段代码给出了正确的输出

    是的,原因是strchr()返回的指针被分配给string指针。同上例,假设输入为

    string = "hello"
    letter = 'l'
    

    strchr(string, letter) 将返回指向第一次出现字符l 的指针,并将其分配给指针string。所以,现在字符串指针指向第一次出现的l。这意味着,现在string

    string = "llo"
    

    在循环体中你正在做的事情

    string++;
    

    这将使字符串指针指向strchr()返回的字符的下一个字符。现在string

    string = "lo"
    letter = `l`
    

    strchr(string, letter) 将返回指向string 当前指向的字符的指针,因为它与字符letter 匹配。由于循环体中的string++,现在字符串将指向下一个字符

    string = "o"
    letter = `l`
    

    并且strchr(string, letter) 将返回NULL 并且循环将退出。 num 的增量与 string 中的字符 letter 一样多。因此第二个 sn-p 给出了正确的输出。

    【讨论】:

    • 感谢您强调关于它并不总是输出字符串 strlen 的部分
    猜你喜欢
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 2013-09-17
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    相关资源
    最近更新 更多