如何使用指针在c中编写自己的strchr?

时间:2017-01-25 23:37:22

标签: c string pointers strchr

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

编写一个名为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;
  }

}

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

3 个答案:

答案 0 :(得分:4)

从手册:

  • char *strchr(const char *s, int c); - &gt;第二个参数是一个int
  • strchr()和strrchr()函数返回指向匹配字符的指针,如果找不到该字符,则返回NULL。
  • 终止空字节被认为是字符串的一部分,    因此,如果将c指定为&#39; \ 0&#39;,这些函数将返回指向终结符的指针。
  • [如果第一个参数恰好为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;
}

答案 1 :(得分: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);
}

请注意,在此上下文中,即使NULL0,使用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:在此上下文中,您无需检查str是否为NULL

注3:&#34;官方&#34; strchr的原型是char *strchr(const char *s, int c);,因此根据您的项目要求,您可能希望更新原型以匹配此原型。

答案 2 :(得分: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本身就会增加。