2016-12-28 2 views
0

Ich tauche in C in Zeiger und Strings ein und ich gewöhne mich immer noch an einige Konzepte. Ich habe versucht, eine Version der strchr() Funktion - die gleiche wie in string.h - zu Studienzwecken zu implementieren, aber etwas Grundlegendes ist immer noch nicht richtig.Könnte jemand mir helfen, diesen strchr() C Segmentierungsfehler zu verstehen?

Hier ist mein Code:

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

Ich versuche, herauszufinden, warum dies ist eine Segmentierung Fehler zurückgegeben. Wenn ich gbd verwende, sagt es mir, dass der Fehler in der letzten printf ist, die versucht, die *b zu drucken.

Sobald my_strchr() einen (char*) str zurückgibt, müsste ich diesen Rückgabewert in einer char Zeigervariable speichern, richtig?

+3

Erfolgt dies bei allen Eingaben oder nur bei Zeichen, die nicht in Ihrer Testzeichenfolge enthalten sind? – usr2564301

+0

@Rad Lexus mit allen Eingabe ... Immer noch versuchen, herauszufinden, was passiert ... – ulissesBR

+2

Zeigen Sie Ihre Eingabe. Auch 'strchr' kann' '\ 0'' suchen. – BLUEPIXY

Antwort

5

Wenn my_strchr das Zeichen in der Zeichenfolge nicht findet, wird NULL zurückgegeben.

In diesem Fall ist bNULL also *b ist undefiniertes Verhalten, das den segfault erklärt.

Vielleicht möchten Sie das Ergebnis my_strchr vor dem Drucken *b, z.B .:

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

Vielen Dank für Ihre Antwort, das war das Problem! Ich löste es, indem ich eine if-Anweisung hinzufügte, um zu testen, ob b NULL ist und nun wie ein Zauber wirkt! Danke allen! – ulissesBR

0

Es gibt eine gewisse Logik Problem zu überprüfen, wie die tuple_cat.

Aber ich denke auch, dass Sie einige Konzepte nicht verstehen, Ihr Code ist aus meiner Sicht nicht sauber.

Ich denke, man habe gerade angefangen in c Codierung so halten Codierung :)

Zuerst ein char * in Ihrer Funktion zurück, sondern Sie definieren Argument der Funktion als

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

In Standard-C können Sie berühre keine Konstante, die du nicht verändern kannst, das ist der Punkt, an dem du eine Konstante deklarierst.

so die Funktion ändern, um

char* my_strchr(char* str, int c) 

Dann ist die richtige Art und Weise ein Zeichen aus einem String zurück ist nicht

return (char*)str; 

aber nur

return str; 

Am Ende Ihres Funktion.

Auf diese Weise senden Sie die Adresse des ersten Zeichens in char * (string). In einem char * tun Sie das, indem Sie einfach den Variablennamen angeben.

Ich möchte Sie ermutigen lesen: https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html

RTFM !!! der char * Teil bei 1.3.4 String Konstanten

Wie auch immer viel Glück in Ihrem Lernen.

+1

Danke @Raphael, ich werde darauf graben. Wie auch immer, der Verweis, dem ich folgte, sagt, dass wenn eine Zeichenfolge als Argument übergeben wird, das Funktionsargument eine Konstante sein sollte, um jegliche Änderungen in der Zeichenkette zu vermeiden. – ulissesBR

+0

Das ist richtig, wenn Sie es nicht ändern. aber dann, was ist der Punkt der Rückgabe eines char *? Wenn Sie nichts damit tun, könnten Sie einfach überprüfen, wie es etwas macht, das in Ordnung ist, dann zurück. Void oder sonst, aber ja, es ist nur Compiler Warnungen zu vermeiden, es ist Empfehlung. –

+3

Das ist nur ein schlechter Rat bezüglich der 'const'-Korrektheit. Sie sollten den Funktionsprototyp für die Standardbibliotheksversion lesen: 'strchr (const char * string, int c)'. In diesem Fall zeigt "const" an, dass der Wert, der an der Stelle gespeichert ist, auf die durch "string" gezeigt wird, nicht modifiziert werden kann; aber der Wert des Zeigers selbst kann modifiziert werden (um zum Beispiel den String zu durchlaufen). Beim Emulieren von Bibliotheksfunktionen ist es am besten, die Standard-Prototypen beizubehalten und zu versuchen, zu verstehen, warum sie auf diese Weise geschrieben sind. OP machte das. –

Verwandte Themen