2016-12-28 14 views
0

私はCでポインタと文字列に潜っていますが、まだいくつかの概念に慣れています。私はstrchr()関数のバージョンを実装しようとしました。これはstring.hと同じですが、学習の目的では基本的なことはまだ正しくありません。ここで誰でも私はこのstrchr()Cセグメンテーションフォールトを理解するのを助けることができますか?

は私のコードです:

#include <stdio.h> 

char* my_strchr(const char* str, int c){ 
    if (str == NULL){ 
    printf("STR is NULL. Finishing the program\n"); 
    return NULL; 
    } 
    while (*str != '\0'){ 
    if (*str == c){ 
     return (char*) str; 
    } 
    str++; 
    } 
    return NULL; 
} 

int main(){ 
    char *a = "Hello World!"; 
    char *b; 
    char c; 

    printf("Type the character you want to find in the Hello World! string:\n"); 
    scanf(" %c", &c); 

    b = my_strchr(a, c); 

    printf("Character found! %c\n", *b); 

    return 0; 
} 

私は、これがセグメンテーションエラーを返している原因を把握しようとしています。 gbdを使用すると、エラーが最後にprintfにあり、*bを印刷しようとしていることがわかります。

(char*) strを返すと、charポインタ変数にこの戻り値を格納する必要があります。

+3

これはすべての入力、またはテスト文字列に表示されない文字のみで起こりますか? – usr2564301

+0

@Rad Lexus with all input ...まだ何が起こっているのか把握しようとしています... – ulissesBR

+2

あなたの入力を表示してください。また 'strchr'は' '\ 0''を検索できます。 – BLUEPIXY

答えて

5

my_strchr文字列内の文字が見つからない場合は、NULLを返します。

この場合、bNULLです。したがって、*bは、segfaultを説明する未定義の動作です。あなたが例えば、*bを印刷する前にmy_strchrの結果をチェックすることをお勧めします

if (b != NULL) { 
    printf("Character found! %c\n", *b); 
} else { 
    printf("Not found...\n"); 
} 
+0

お返事いただきありがとうございます、これが問題でした!私はbがNULLで、今は魅力のように動作するかどうかをテストするif文を追加して解決しました!みんな、ありがとう! – ulissesBR

0

ありtuple_catのようないくつかのロジックの問題が言われています。

しかし、私はあなたがいくつかの概念を理解していないと思う、あなたのコードは私の視点からきれいではありません。

私はあなたがちょうどそうコーディング:)

まず、あなたの関数内で、char *を返す保つCでコーディングし始めたと思いますが、あなたはあなたができる標準Cでは

char* my_strchr(const char* str, int c) 

として関数の引数を定義します定数に触れないでください。それを変更することはできません。それは定数を宣言する点です。

ので、次に文字列から文字を返すための正しい方法は

return (char*)str; 

が、あなたの終わりにちょうど

return str; 

ない

char* my_strchr(char* str, int c) 

に機能を変更します関数。

この方法で、char *(文字列)の最初のcharのアドレスを送信します。 char *では、変数名を与えるだけでそれを行います。

私がお読みになることをお勧め:https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html

RTFMを! char *の部分は1.3.4文字列定数

とにかくあなたの学習には幸運があります。

+1

ありがとう@ラファエル、私はそれを掘り下げます。とにかく、私が従っていたリファレンスでは、文字列を引数として渡すとき、関数の引数は定数でなければならず、文字列の変更を避ける必要があります。 – ulissesBR

+0

それはあなたがそれを変更しないなら、そうです。しかし、char *を返すことのポイントは何ですか?もしあなたがそれを使って何もしなければ、あなたはそれが何かOKを返してから戻ってくるようにチェックできます。無効にするか、それ以外はコンパイラの警告を避けるだけです。 –

+3

これは 'const'-correctnessに関するちょっとしたアドバイスです。 'strchr(const char * string、int c)'標準ライブラリ版の関数プロトタイプを読むべきです。この場合、 'const'は、' string'が指し示す位置に格納された値を変更できないことを示します。ポインタ自体の値を変更することができます(たとえば、文字列をループする)。ライブラリ関数をエミュレートするときは、標準プロトタイプを貼り付け、そのように書かれた理由を理解しようとするのが最善です。 OPがこれをやっていた。 –

関連する問題