2017-01-25 4 views
1

Ok, also habe ich hier einen Auftrag von meinem Professor. Hier ist es:Wie schreibe ich dein eigenes strchr in c mit Zeigern?


Schreiben Sie eine Funktion namens strchr406. Es ist 2 Parameter übergeben: eine Zeichenfolge und ein Zeichen Hier ist der Prototyp für die Funktion: char * strchr406 (char str [], char ch); Die Funktion sollte einen Zeiger auf die erste Instanz von ch in str zurückgeben. Zum Beispiel:

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 

Er bittet uns, unsere eigene Version von strchr mit Zeigern zu schreiben. Ich habe online nach Ressourcen gesucht, aber nichts davon entspricht dem, was er von uns verlangt. Ich arbeite mit einer Gruppe anderer Studenten zusammen, und keiner von uns konnte das herausfinden.

Wie geben wir "s + 1" zurück?

Bisher habe ich dies: (ich es auch online gestellt, wenn das einfacher ist: 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; 
    } 

} 

Ich erhalte seltsame Ausgänge. Jede Hilfe wird geschätzt.

+1

Nicht klar, was Ihr Problem ist. 'strchr' ist eine ziemlich einfache Funktion. Sie können jedoch keinen Zeiger oder eine ganze Zahl von Ihrer Funktion zurückgeben, diese Zuordnung ist Unsinn wie angegeben (und zu lehren, "0" als Nullzeigerkonstante zu verwenden, ist ein schlechter Stil; verwenden Sie das Makro 'NULL'). Vielleicht bedeutet Ihr Prof ein _null Zeiger_, der nicht der Integer "0" ist? Aber dann können Sie nicht wie eine Zeichenfolge drucken, sondern explizit testen und etwas anderes drucken (das ist die Idee von Null-Zeigern). – Olaf

+3

Und posten Sie keine Bilder von Text. Sie sollten es zumindest als Text einfügen. – Olaf

+0

Ich werde es jetzt bearbeiten. – nastypluto

Antwort

4

Aus dem Handbuch:

  • char *strchr(const char *s, int c); -> das zweite Argument ist ein int
  • Die strchr() und strrchr() Funktionen geben einen Zeiger auf den gefundenen Zeichen oder NULL, wenn das Zeichen nicht ist gefunden.
  • Das abschließende Nullbyte wird als Teil der Zeichenfolge betrachtet. Wenn also c als '\ 0' angegeben ist, geben diese Funktionen einen Zeiger auf den Terminator zurück.

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

oder noch kürzer

  • [NULL sein gibt es kein definiertes Verhalten, wenn das erste Argument geschieht]:


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

    Es gibt eine ein paar kleine Dinge, die du hinzufügen oder neu organisieren solltest de, damit es funktioniert.

    Erstens, dieses Stück Code

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

    nicht am Ende der Zeichenfolge zu stoppen und Schleifen werden fortgesetzt, bis es Ihre char irgendwo nach der Zeichenfolge in dem virtuellen Speicher des Prozesses findet.

    So sollten Sie wahrscheinlich eine Bedingung zum Anhalten, dass die Kontrollen für das Ende des Strings (Strings in C mit dem char endet \0, ASCII-Code = 0):

    while (*str != '\0') 
    

    Die zweite Sache, Sie zu vergleichen sind, ch mit dem aktuellen Zeichen der Zeichenfolge nach der Schleife.Sie sollten diesen Code wahrscheinlich innerhalb der Schleife verschieben: Sie müssen jedes Zeichen der Zeichenfolge gegen ch überprüfen. Außerdem müssen Sie keinen Index verwenden und den Zeiger str inkrementieren. So können Sie die Variable index loswerden. Wenn Sie zu jeder Zeit in Ihrer Schleife die richtige ch finden, dann können Sie den Zeiger mit str direkt dorthin zurückbringen. Wenn Sie aus Ihrer Schleife erhalten, bedeutet dies, dass Sie nicht die ch innerhalb str gefunden haben und dann können Sie zurückkehren NULL (cf man strchr für mehr auf Rückgabewerte).

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

    Hinweis, dass auch in diesem Zusammenhang allerdings NULL ist 0, es besser ist, NULL zu verwenden, da Sie sollen einen Zeiger zurück.

    Letzte Sache, wenn man genau wie strchr tun will, dann, wenn ch ist '\0' sollten Sie den Zeiger auf die '\0' am Ende des Strings str zurückzukehren. Von dem Mann: 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. So wird Ihr Code:

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

    Hinweis: Danke an @chux für das Zeigen dieser letzten Sache.

    Hinweis 2: In diesem Kontext müssen Sie nicht überprüfen, ob strNULL ist.

    Hinweis 3: Der "offizielle" Prototyp für strchr ist char *strchr(const char *s, int c);. Je nach den Anforderungen Ihres Projekts können Sie Ihren Prototyp entsprechend diesem Projekt aktualisieren.

    +0

    Sie haben Recht. Aktualisiert. Danke @chux – Julien

    +1

    Hinweis: 'return' ist ** nicht ** eine Funktion. 'return (NULL);' - >> 'return NULL;' – wildplasser

    +0

    "Beachten Sie, dass in diesem Kontext, obwohl NULL 0" - Fehler ist, das für viele Implementierungen falsch ist. Normalerweise ist das 'NULL' ** Makro **' (void *) 0'. Selbst wenn es für eine bestimmte Implementierung "0" war, kann und soll man sich nicht darauf verlassen. – Olaf

    3

    Hier sind Sie

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

    Das Programm Ausgabe

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

    Sagen Sie Ihre Professor ist, dass es richtig sein wird, die Funktion wie

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

    Darüber hinaus ist die Standardfunktion hat zu erklären, die folgende Erklärung

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

    weil Zeichenliterale in C den Typ int haben. So könnte man die Funktion auch die folgende Art und Weise

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

    Was Ihre Funktion schreibt, dann gibt es keinen Sinn, die Variable index zu verwenden, weil der Zeiger str selbst erhöht wird.

    +1

    Und sagen Sie Ihrem Professor, dass der Typ des 2. Arguments zu strchr() ist "int", nicht "char" – wildplasser

    +0

    Ja, ich komme aus anderen Sprachen und haben immer noch Probleme mit Zeigern. Übrigens, was machen Ihre Print-Anweisungen eigentlich? Ich meine Wie ist strchr406 (s, 'b') gleich (s + 1)? – nastypluto

    +0

    @nastypluto Das Ergebnis der Vergleiche in C hat den Typ int. Wenn also zum Beispiel zwei Zeiger gleich sind, ist das Ergebnis ihres Vergleichs gleich 1. In dieser Anweisung printf ("strchr406 (s, 'b') == s + 1 ist% d \ n", strchr406 (s, 'b') == s + 1); Ich zeige, dass der zurückgegebene Zeiger in der Tat gleich s + 1 ist. –