2017-01-25 8 views
1

だから私は教授から任せられています。ここには:ポインタを使ってCで独自の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; 
    } 

} 

私は奇妙な出力を取得しています。どんな助けもありがとうございます。マニュアルから

+1

あなたの問題が何であるかは明らかではありません。 'strchr'は非常に単純な関数です。しかし、あなたの関数からポインタや整数を返すことはできません。与えられたようにその割り当てはナンセンスです(NULLポインタ定数が '0'を使うよう教えることは悪いスタイルです;' NULL'マクロを使います)。多分、あなたのprofは、整数 '0'と同じではない_nullポインタ_を意味しますか?しかし、文字列のようにこれを印刷することはできませんが、明示的にテストして別のものを印刷します(ヌルポインタの考え方です)。 – Olaf

+3

テキストの画像を投稿しないでください。少なくともテキストとして貼り付ける必要があります。 – Olaf

+0

今すぐ編集します。 – nastypluto

答えて

4

  • char *strchr(const char *s, int c); - >第二引数がint
  • strchr()で文字がない場合はstrrchr()関数は一致した文字またはNULLへのポインタを返します見つかりました。
  • 終端のNULLバイトは文字列の一部とみなされ、 となります。したがって、cが '\ 0'として指定された場合、これらの関数はターミネータへのポインタを返します。

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

あるいは短い[最初の引数がNULLであることを起こる場合は何も定義された動作はありません]:


char *strchr42a(char *str, int ch) 
{ 
do  { 
     if (*str == ch) return str; 
     } while (*str++) ; 
return NULL; 
} 
3

ありますあなたの共同体で追加または再編成すべき小さなもののカップルそれを動作させるためにde。

まず、コード

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

のこの作品は、あなたの文字列の末尾に停止しません、それはプロセスの仮想メモリ内の文字列の後にどこかのcharを見つけるまでループし続けます。

だから、あなたはおそらく、文字列の末尾をチェック(Cの文字列がchar \0、= 0 ASCIIコードで終了)することを停止するための条件が必要です:

while (*str != '\0') 

第二のものは、あなたが比較しているがchをループの後の文字列の現在の文字で置き換えます。ループ内でこのコードを移動する必要があります。文字列のすべての文字をchと照合する必要があります。また、インデックスを使用してポインタstrをインクリメントする必要はありません。したがって、変数indexを取り除くことができます。いつでもあなたのループ内で正しいchを見つけた場合、あなたは直接strを使用して、それへのポインタを返すことができます。あなたは蚊帳の外に出た場合、それはあなたがstr内部chを見つけられませんでしたし、次にあなたがNULL(CF戻り値の詳細についてman strchr)を返すことができることを意味します。 NULL0であっても、あなたがポインタを返すことになっていることから、この文脈では、それはNULLを使用することをお勧めしますことを

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

注意。

最後の事あなたは正確にstrchrのように実行したい場合は、その後、ch'\0'ある場合は、文字列strの終わりに'\0'へのポインタを返す必要があります。男から: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); 
} 

注:この最後のものを指してくれてありがとうございます。

注2:あなたはstrは、この文脈でNULLであるかどうかを確認する必要はありません。

注3:strchrの "公式の"プロトタイプはchar *strchr(const char *s, int c);です。したがって、プロジェクト要件に応じて、このプロトタイプに合わせてアップデートしたいかもしれません。ここで

+0

あなたは正しいです。更新しました。ありがとう@chux – Julien

+1

注: 'return'は**関数ではありません**。 'return(NULL);' - >> 'return NULL;' – wildplasser

+0

"この文脈では、NULLが0" - errであっても、それは多くの実装にとって間違っています。通常、 'NULL' **マクロ**は'(void *)0'です。特定の実装では「0」だったとしても、その実装に依存することはできません。 – Olaf

3

あなたはプログラムの出力は、また、標準機能があり

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

のような関数を宣言するために正しいだろうというあなたの教授を言う

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

ある

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

です次の宣言

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

も、次のような方法は、その後、ポインタstrので、変数indexを使用しても意味がない機能を書くことができ、それ自体が増加しています。

+1

strchr()の2番目の引数の型は 'char'ではなく' int'です。 – wildplasser

+0

ええ、私は来ています他の言語からは、まだポインタにいくつかの問題があります。ところで、あなたのプリントステートメントは実際に何をしていますか?私はstrchr406(s、 'b')はどのように(s + 1)と等しいのですか? – nastypluto

+0

@nastypluto Cでの比較の結果はint型です。たとえば、2つのポインタが互いに等しい場合、比較結果は1になります。この文では、printf( "strchr406(s、 'b')== s + 1は%d \ n"、strchr406 s、 'b')== s + 1)となる。実際に返されたポインタがs + 1に等しいことを示しています。 –

関連する問題