1

好的,所以我的教授给我一个任务。这里是:


编写一个名为 strchr406 的函数。它传递了 2 个参数:一个字符串和一个 char 下面是函数的原型: char *strchr406(char str[], char ch); 该函数应返回指向 str 中第一个 ch 实例的指针。例如:

char s[ ] = "abcbc";
strchr406(s, 'b');   // returns s + 1 (i.e., a pointer to the first 'b' in s)
strchr406(s, 'c');   // returns s + 2
strchr406(s, 'd');   // returns 0

他要求我们使用指针编写我们自己的 strchr 版本。我在网上查找资源,但没有一个符合他要求我们做的事情。我正在与一群其他学生一起工作,我们谁也无法弄清楚这一点。

我们如何返回“s + 1”?

到目前为止,我有这个:(如果这更容易,我也把它放在网上:https ://repl.it/FVK8 )

#include <stdio.h>
#include "string_problems.h"

int main() {
  char s[ ] = "abcbc";
  strchr406(s, 'b');   // returns s + 1 (i.e., a pointer to the first 'b' in s)
  strchr406(s, 'c');   // returns s + 2
  strchr406(s, 'd');   // returns 0
  printf("this should return %s\n", strchr406(s, 'c'));
  return 0;
}

char *strchr406(char str[], char ch) {
  char *p = str;
  int index = 0;
  while (*str != ch) {
    ++str;
    ++index;
  }
  if (*str == ch) {
    return p + index;
  } else {
    return 0;
  }

}

我得到奇怪的输出。任何帮助表示赞赏。

4

3 回答 3

4

从手册:

  • char *strchr(const char *s, int c);--> 第二个参数是一个 int
  • strchr() 和 strrchr() 函数返回一个指向匹配字符的指针,如果找不到该字符,则返回 NULL。
  • 终止的空字节被认为是字符串的一部分,因此如果 c 被指定为 '\0',这些函数将返回一个指向终止符的指针。
  • [如果第一个参数恰好为 NULL,则没有定义的行为]

char *strchr42(char *str, int ch)
{
for (;; str++) {
        if (*str == ch) return str;
        if (!*str) return NULL;
        }
return NULL;
}

甚至更短:


char *strchr42a(char *str, int ch)
{
do      {
        if (*str == ch) return str;
        } while (*str++) ;
return NULL;
}
于 2017-01-25T23:55:13.057 回答
3

您应该在代码中添加或重新组织一些小东西以使其正常工作。

首先,这段代码

  while (*str != ch) {
    ++str;
    ++index;
  }

不会在你的字符串末尾停止,并且会继续循环,直到它在进程的虚拟内存中的字符串后面的某个地方找到你的字符。

因此,您可能应该有一个停止检查字符串结尾的条件(C 中的字符串以 char 结尾\0,ASCII 码 = 0):

while (*str != '\0')

第二件事,您正在ch与循环后字符串的当前字符进行比较。您可能应该将此代码移动到循环中:您需要检查字符串的每个字符是否与ch. 此外,您不需要同时使用索引和递增指针str。所以你可以摆脱index变量。如果在您的循环中的任何时候您找到正确的,ch那么您可以使用直接返回指向它的指针str。如果您退出循环,则意味着您没有找到ch内部str,然后您可以返回NULL(参见man strchr返回值的更多信息)。

char *strchr406(char str[], char ch)
{
     while (*str != '\0')
     {
          if (*str == ch)
          {
               return (str);
          }
          str++;
     }
     return (NULL);
}

请注意,在这种情况下,即使NULLis 0,最好使用它,NULL因为您应该返回一个指针。

最后一件事,如果你想做完全一样strchr的,那么如果ch'\0'应该返回指向'\0'字符串末尾的指针str。来自男人:The terminating null byte is considered part of the string, so that if c is specified as '\0', these functions return a pointer to the terminator。所以你的代码变成:

char *strchr406(char str[], char ch)
{
     while (*str != '\0')
     {
          if (*str == ch)
          {
               return (str);
          }
          str++;
     }
     /**                                                                                                                    
      * if ch is '\0', you should return                                                                                    
      * the pointer to the `\0` of the string str                                                                           
      */                                                                                                                    
     if (*str == ch)                                                                                                        
     {                                                                                                                      
          return (str);
     }
     return (NULL);
}

注意:感谢@chux 指出最后一件事。

注意 2:您不需要检查是否strNULL此上下文中。

注意 3:strchr 的“官方”原型char *strchr(const char *s, int c);取决于您的项目要求,您可能希望更新您的原型以匹配此原型。

于 2017-01-25T23:55:55.517 回答
3

给你

#include <stdio.h>

char * strchr406( const char str[], char ch ) 
{
    while ( *str && *str != ch ) ++str;

    return ( char * )( ch == *str ? str : NULL );  
}

int main(void) 
{
    char s[ ] = "abcbc";

    printf( "strchr406(s, 'b') == s + 1 is %d\n", strchr406(s, 'b') == s + 1 );
    printf( "strchr406(s, 'c') == s + 2 is %d\n", strchr406(s, 'c') == s + 2 );
    printf( "strchr406(s, 'd') == 0 is %d\n", strchr406(s, 'd') == 0 );
    printf( "this should return %s\n", strchr406(s, 'c'));

    return 0;
}

程序输出为

strchr406(s, 'b') == s + 1 is 1
strchr406(s, 'c') == s + 2 is 1
strchr406(s, 'd') == 0 is 1
this should return cbc

说你的教授,声明这个函数是正确的

char * strchr406( const char str[], char ch );
                  ^^^^^ 

此外,标准函数具有以下声明

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

因为 C 中的字符文字具有 int 类型。所以你甚至可以通过以下方式编写函数

char * strchr406( const char str[], int ch ) 
{
    unsigned char c = ch;

    while ( *str && ( unsigned char )*str != c ) ++str;

    return ( char * )( c == ( unsigned char )*str ? str : NULL );  
}

至于你的函数,那么使用变量是没有意义的,index因为指针str本身会增加。

于 2017-01-25T23:56:53.227 回答