annA: Strings vergleich

hallo zusammen,

ich habe zwei char-Arrays:
arr = "while"
arr2 = "whhile"

gibt es eine einfache Methode (fertige Funktion) in C einzelne
Zeichen aus einem "String" zu löschen? Wie macht mensch sowas
am geschicktesten (schnellsten)?

Danke
annA

  1. Halihallo annA

    gibt es eine einfache Methode (fertige Funktion) in C einzelne
    Zeichen aus einem "String" zu löschen? Wie macht mensch sowas
    am geschicktesten (schnellsten)?

    Was meinst du mit "einzelne Zeichen" löschen? - Ein Auftreten eines
    Zeichens an bestimmtem Index, oder ein gewisses Zeichen ganz aus dem
    String löschen?

    Ich berufe mich auf:
    http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_5.html#SEC57

    falls du einfach einen bestimmten Index löschen möchtest, wäre
    bestimmt ein memncpy das effizienteste (zwei mal memncpy in einen
    neuen String und zwar so, dass der zu löschende Index eben nicht
    mitkopiert wird).

    falls das Auftreten eines bestimmten Zeichens (Index unwichtig)
    gemeint ist, würde ich mit einem Pointer über den
    Inputstring "fahren" und eben nur erlaubte Zeichen in den
    Ergebnisstring kopieren.

    Viele Grüsse

    Philipp

    1. Halihallo nochmals

      Was meinst du mit "einzelne Zeichen" löschen? - Ein Auftreten eines
      Zeichens an bestimmtem Index, oder ein gewisses Zeichen ganz aus dem
      String löschen?

      Oder wie der Threadtitel andeutet: die Strings vergleichen.?

      Nun, auch hier würde ich mit jeweils einem Pointer pro String
      arbeiten, der über die Strings iteriert. Befinden sich nicht an
      beiden dereferenzierten Pointern dasselbe Zeichen, unterscheidet
      sich der String. Was du dann tun willst, habe ich noch nicht
      verstanden.

      Viele Grüsse

      Philipp

      1. Hi Phillip,

        der Titel war etwas irreführen, zugegeben :o)
        tatsächlich will ich zwei Strings vergleichen, bei dem
        einen aber eben immer ein Zeichen löschen um zu schauen,
        ob ein Tippfehler vorliegt.
        Das mit dem memcpy werde ich mir mal anschauen, auch wenn
        ich wieder von dem "Mehrpassparser"-Projekt abgerückt bin,
        kann man sowas doch immer mal gebrauchen :o)

        Liebe Grüße
        annA

        1. entschuldige Philipp, habe Deinen Namen nicht richtig geschrieben

        2. Halihallo annA

          der Titel war etwas irreführen, zugegeben :o)
          tatsächlich will ich zwei Strings vergleichen, bei dem
          einen aber eben immer ein Zeichen löschen um zu schauen,
          ob ein Tippfehler vorliegt.

          Huh? - Wie definierst du einen Tippfehler? - Und wozu musst du dann
          immer ein Zeichen löschen?
          Du würdest also n-Mal das Zeichen an n-tem Index löschen und dann den
          String auf Gleichheit prüfen? - Schneller und effizienter ginge es, wenn man mit zwei Pointern über die Strings iteriert und bei Nichtübereinstimmen überprüft, ob das "nächste" Zeichen wieder übereinstimmt. Das könnte man so als Tippfehler definieren. Dieser Algorithmus würde performanter sein. Ein kleines Beispiel, wie dies gemeint ist, steht unten.

          Das mit dem memcpy werde ich mir mal anschauen, auch wenn
          ich wieder von dem "Mehrpassparser"-Projekt abgerückt bin,
          kann man sowas doch immer mal gebrauchen :o)

          Mehrpassparser-Projekt? - Was hattest du denn da vor? :-)

          ---

          #include <stdlib.h>
          #include <stdio.h>

          int is_tipp_error(char *str1, char *str2) {
            while ((str1 != NULL) && (str2 != NULL)) {
              if (*str1 != *str2) { // huh, Tippfehler???
                if ((*(str1+1) == *str2) || (*(str2+1) == *str1)) {
                  // OK, next char matches again => Tippfehler wahrscheinlich
                  return 1;
                } else {
                  return 0; // da ist mehr als ein Zeichen falsch
                                  // => kein Tippfehler!
                }
              }
              str1++; str2++;
            }
            return 0;
          }

          int main(void) {
            char str1[] = "Philipp";   /* :-) */
            char str2[] = "Phillip";
            char str3[] = "annA";

          printf("%s <=> %s : %d\n", str1, str2, is_tipp_error(str1,str2) );
            printf("%s <=> %s : %d\n", str2, str3, is_tipp_error(str2,str3) );
            printf("%s <=> %s : %d\n", str3, str1, is_tipp_error(str3,str1) );

          return 0;
          }

          ---

          so mal auf die schnelle hingeplappert. Falls ein Zeichen nicht
          übereinstimmt, wird einfach geprüft, ob das "nächste" Zeichen
          (entweder von str1 oder str2) wieder übereinstimmt; falls ja kann
          man von einem Tippfehler ausgehen, falls nein ist der
          String "definitiv" verschieden.
          Hängt eben alles von deiner Definition von Tippfehler ab. Und zudem:
          der Source-Code von oben beachtet nur das erste Auftreten! - Das ist
          natürlich nicht im Sinne der Aufgabe; soll auch nur den "Sinn" oder
          das Vorgehen verdeutlichen...

          Viele Grüsse

          Philipp

          1. Huhu

            Huh? - Wie definierst du einen Tippfehler?

            Ich gehe hier immer von Wörtern eine Länger sagen wir mal
            größer/ gleich 4 aus:
            Zwei Zeichen sind vertauscht: whlie
            Ein Zeichen fehlt: wile
            Ein Zeichen zuviel: whille
            Problematisch wirds, wenn der Programmiere eine Variable wile
            nennt, dann muß der Parser erst weiterschauen, was genau gemeint
            ist, deshalb müsste der Parser mehrmals laufen... ist ziemlich auf-
            wendig, vorallem, wenn man wie ich, Filepointerdings nicht mag,
            und immer im File hin und her springen muss :o)
            naja, vielleicht baue ich an ein paar Stellen eine solche
            semantische Prüfung ein, nur zum zeigen, das es gehen könnte

            Mehrpassparser-Projekt? - Was hattest du denn da vor? :-)

            einen Compiler schreiben (ist auch schon fast fertig *freu*
            jetzt fehlt nur noch der Interpreter und eben solche schönen
            Kleinigkeiten wie diese Problem hier)

            Den Rest Deiner Antwort werde ich mir heute abend mal anschauen,
            jetzt muß ich erstmal arbeiten und dann gibts ja diese Semster
            leider noch mehr als Compiler zu machen

            Danke für die ausführliche Antwort

            Viele Grüße
            annA

            1. Halihallo annA

              Problematisch wirds, wenn der Programmiere eine Variable wile
              nennt, dann muß der Parser erst weiterschauen, was genau gemeint
              ist, deshalb müsste der Parser mehrmals laufen... ist ziemlich auf-
              wendig, vorallem, wenn man wie ich, Filepointerdings nicht mag,
              und immer im File hin und her springen muss :o)
              naja, vielleicht baue ich an ein paar Stellen eine solche
              semantische Prüfung ein, nur zum zeigen, das es gehen könnte

              Aha, ein gutmütiger Parser wird das. Aber Tippfehler nicht bestrafen
              halte ich für Programmiersprachen mehr als Nachteil, denn als
              Vorteil. Aber wurscht :-)

              Mehrpassparser-Projekt? - Was hattest du denn da vor? :-)
              einen Compiler schreiben (ist auch schon fast fertig *freu*
              jetzt fehlt nur noch der Interpreter und eben solche schönen
              Kleinigkeiten wie diese Problem hier)

              Klingt sehr interessant.

              BTW: Bzgl. des geposteten Sources:
              while ((str1 != NULL) && (str2 != NULL))

              muss natürlich heissen:

              while (*str1 && *str2) { ... }

              und noch ein paar andere Sachen, deren Erwähnung sich nicht
              lohnen, denn dieses Beispiel muss nicht perfekt sein...

              Viele Grüsse

              Philipp

              1. Also, die Programmiersprache wird ohnehin niemals jemand benutzen,
                die ist nämlich ziemlicher Quatsch (vom Dozenten vorgegeben)
                aber um mal zu verstehen, was so ein Compiler macht,
                ist es schon ganz schön auch mal solche Probleme wie Vertipper
                zu betrachten, um dann festzustellen, es ist technisch ein so
                großer Aufwand, dass es sich "fast" nicht lohnt (sonst wäre es ja
                auch bei Compilern schon implementiert)
                Auf jeden Fall schimpfe ich jetzt nicht mehr über C, warum um Himmels
                willen die Variablen immer am Anfang deklariert sein müssen...
                und bin froh, das es bei unserer Sprache auch so ist :o)
                So einen Compiler schreiben macht schon Spass (auch wenns doch
                arg aufwendig ist)

                viele grüße
                annA