strcmp selfmade. Fußgesteuerte Schleife? Abbruch nach dem ersten Zeichen



  • mngbd schrieb:

    while (str[a] == str2[a] || str[a] !=  '\0' || str2[a] !=  '\0')
        a++;
    return str[a] - str2[a];
    

    Das sollte hinhauen, hab's aber nicht getestet.

    Danke, ich habe es nen kurzen Moment nach meinem Post eh verstanden^^
    Aber wenn in str[a] 5 steht und in str2[a] 6 steht wird an die Funktion 1 zurrück geliefert.
    ABER draußen rufe ich das auf, frage ab ob der zurrückgelieferte Wert 1 ist, und es geht nicht.
    Dann habe ich es mit ungleich 0 probiert, geht auch nicht.
    Mit gleich 0 auch.

    Ich poste mal den Code.

    #include <stdio.h>
    #include <conio.h>
    
    int menu (void);
    int MyStrLen (char[]);
    int MyStrCmp (char[], char[]);
    
    void main (void)
    {
    	int ant;
    	char str[50], str2[50];
    
    	while (ant = menu())
    	{
    		switch (ant)
    		{
    		case 1:
    			printf("STRLEN\n");
    			printf ("Bitte String eingeben: ");
    			gets (str);
    			printf ("\nLaenge: %d\n", MyStrLen (str));
    			break;
    		case 2:
    			printf ("Bitte String eingeben: ");
    			gets (str);
    			printf ("Bitte String2 eingeben: ");
    			gets (str2);
    			if (MyStrCmp(str, str2) == 0)
    			{
    				puts("0");
    			}
    			if (MyStrCmp(str, str2) = -1)
    			{
    				puts("1");
    			}
    			if (MyStrCmp(str, str2) != 0)
    			{
    				puts("-1");
    			}
    			break;
    		default:
    			printf ("Falsche Eingabe!\n");
    		}
    		getch();
    	}
    }
    
    int menu (void)
    {
    
    	int ant;
    
    	puts ("\n\n*** Mein Menue Programm ***\n\n"); // puts am ende automatisch zeilenschaltung kann keine formatierung ausgeben. formatierung zB = "%d", a
    	puts (" 0 ... Ende");
    	puts (" 1 ... Stringlänge");
    	puts (" 2 ... Stringverlgiech");
    
    	printf ("Bitte Ihre Wahl: ");
    	scanf("%d", &ant);
    	flushall ();
    
    	return ant;
    }
    int MyStrLen (char str[])
    {
    	int i = 0;
    	while (str[i] != '\0')
    		i++;
    
    	return i;
    }
    
    int MyStrCmp (char str[], char str2[])
    {
    
    int a;
    	a = 0;
    	while (str[a] == str2[a] || str[a] !=  '\0' || str2[a] !=  '\0');
    	{
    		a++;
    	}
    	return str[a] - str2[a]; 
    
    }
    


  • ;fricky schrieb:

    [
    nö, mache ich z.b. nie. ich benutze auch nie NULL, sondern immer 0.
    aber 0 ist nicht '0', das weisste ja wohl.
    🙂

    \0 ist eine binäre Null die am Ende jedes Char Arrays steht und eine extra Stelle ein nimmt.



  • Oha. Schau Dir das noch mal genauer an 😋



  • c.nub schrieb:

    ;fricky schrieb:

    [
    nö, mache ich z.b. nie. ich benutze auch nie NULL, sondern immer 0.
    aber 0 ist nicht '0', das weisste ja wohl.
    🙂

    \0 ist eine binäre Null die am Ende jedes Char Arrays steht und eine extra Stelle ein nimmt.

    0 ist Null. Halt Nichts. Was Du meinst sind C-Konventionen.



  • Tut mir leid, aber ich sehe mir die letzte Stunde das selbe an^^ und ich komm fast garnicht weiter. Wenigstens nen Tipp geben oder sagen wo der Fehler liegt bitte 😛



  • c.nub schrieb:

    \0 ist eine binäre Null die am Ende jedes Char Arrays steht und eine extra Stelle ein nimmt.

    Ganz genau. Und statt '\0' (Nullzeichen) kann man eben auch sagen: 0 (Zahl Null), weil in C die Zeichen auch nur Zahlen sind. Deshalb könnte man die Schleife noch weiter verkürzen. Aber erstmal sollten wir sie reparieren:

    while (str[a] == str2[a] || str[a] !=  '\0' || str2[a] !=  '\0');   //<-- das ; muss weg!!
    // das ; ist sehr unglücklich (aber syntaktisch erlaubt, daher kein Fehler)
    // mit dem ; hängt von der Schleife nur eine Anweisung ab, die nichts tut,
    // und der Rest kommt nachher, und ist nicht mehr in der Schleife.
    
    // also ohne das ;
    while (str[a] == str2[a] && str[a] !=  '\0' && str2[a] !=  '\0')
    // ausserdem hier zweimal UND statt ODER, weil alle drei zutreffen müssen
    
    // nun verkürzen wir auf
    while (str[a] == str2[a] && str[a] != 0 && str2[a] != 0)
    // und weiter auf
    while (str[a] == str2[a] && str[a] && str2[a])
    // herrlich, oder?
    

    Das hatte ich vorher unterschlagen, weil ich dich am Anfang nicht überfordern wollte.

    NACHTRAG:
    Also in aller Klarheit: zur while -Schleife gehört nur die nächste Anweisung oder der nächste Block mit {}. In C wird jede Anweisung mit ; beendet, also sieht eine Anweisung, die nichts tut, so aus:

    ;
    

    🙂

    fricky schrieb:

    keine ahnung was der standard verlangt, aber eine wohldefinierte ordnung haste (laut standard) nur bei '0' bis '9', alle anderen zeichen können total durcheinander sein (hat letztens erst einer angemerkt hier, ich glaube bashar oder supertux war das).

    Ich geb's zu, ich hab nicht im Standard nachgeschlagen sondern auf Wikipedia.

    An die Sache mit der Ordnung ich kann mich erinnern. Das hatte ich ins Rollen gebracht, als ich meinte, dass EBCDIC völlig absurd ist. Aber eigentlich ist das doch ganz gleichgültig. Irgendeine wohldefinierte Ordnung wird man schon bekommen, auch wenn sie anders aussieht, als man erwartet. Wenn man eine sinnvolle Ordnung will, muss man eben ASCII oder sowas nehmen.



  • \0 ist eine binäre Null die am Ende jedes Char Arrays steht und eine extra Stelle ein nimmt.

    Nein. Es gibt in C keinen Datentyp "string".

    Was soll bitte eine "binäre Null" sein ? Gibt's denn auch eine Dezimale ???



  • Danke für die super Erklärung, gibt ja voll viele möglichkeiten etwas auszudrücken o_O
    Habe das nun ausgebessert.
    Nehmen wir den Fall, dass beide Variablen gleich sind.
    Dann hat str[a] und str2[a] den selben Wert, dh. return 0;
    Aber, die Ausgabe funktioniert nicht.
    Als ich noch meine Startversion hatte, wo es nach dem 1. Zeichen abgebrochen hat, hat die Ausgabe funktioniert, und ich habe nichts verändert.



  • Also oben frage ich ab ob MyStrCmp 0 ist, wenn ja, soll es 0 ausgeben, funktioniert nicht.



  • Scheppertreiber schrieb:

    Nein. Es gibt in C keinen Datentyp "string".

    naja, es gibt typedef, #define, z.b. typedef char string;* oder sowas.

    Scheppertreiber schrieb:

    Was soll bitte eine "binäre Null" sein ?

    alle bits sind 0, so ist das wohl gemeint.

    c.nub: probier mal ungefähr so:

    int MyStrCmp (char *a, char *b)
    {
        for(;;)
        {
            if (*a != *b)             // aktuelles zeichen ungleich?
                return *a - *b;       // irgendwas !=0 zurückgeben
            else if (*a + *b == 0)    // beide am ende?
                break;                // ok, 0 zurückgeben
            a++;                      // beide ...
            b++;                      // ... eins weiterzählen
        }
        return 0;    
    }
    

    ^^ ungetestet
    🙂



  • ;fricky schrieb:

    c.nub: probier mal ungefähr so:

    int MyStrCmp (char *a, char *b)
    {
        for(;;)
        {
            if (*a != *b)             // aktuelles zeichen ungleich?
                return *a - *b;       // irgendwas !=0 zurückgeben
            else if (*a + *b == 0)    // beide am ende?
                break;                // ok, 0 zurückgeben
            a++;                      // beide ...
            b++;                      // ... eins weiterzählen
        }
        return 0;    
    }
    

    ^^ ungetestet
    🙂

    Naja, ich habe ja Arrays, dh ich soll das ganze in der while Schleife einfügen?



  • c.nub schrieb:

    Naja, ich habe ja Arrays, dh ich soll das ganze in der while Schleife einfügen?

    wenn's unbedingt 'while' sein muss, dann mach aus dem 'for(;;)' ein 'while(1)'. aber schau dir meinen code mal an, damit du das prinzip checkst (entweder ungleich oder beide 0), dann kannstes auch anders programmieren.
    🙂



  • Wow, danke es funktioniert.
    Ehrlich, alleine wär ich da nie drauf gekommen.
    Die Ausgabe habe ich geändert, funktioniert auch super.
    Danke und schönen Abend noch.
    Habe sicher bald iwann wieder ne Frage^^



  • c.nub schrieb:

    Wow, danke es funktioniert.
    Ehrlich, alleine wär ich da nie drauf gekommen.
    Die Ausgabe habe ich geändert, funktioniert auch super.
    Danke und schönen Abend noch.
    Habe sicher bald iwann wieder ne Frage^^

    deine logischen fehler scheint hier nur einer bemerkt zu haben. von fertig vorgekautem code hast du nicht wirklich einen gewinn.



  • Ja stimmt, aber ich habe einige male (auch im C++ Forum) betont, dass ich Tipps brauche, oder Codeteile sprich 1-2 Zeilen die mir sagen wie ich weiter machen soll.
    Und ja, das sind die selben Leute hier^^
    Außerdem habe ich den Code jetzt eh verstanden. Alleine umsetzen... weiß nicht.



  • c.nub schrieb:

    Alleine umsetzen... weiß nicht.

    Du warst aber auf einem guten Weg. Deine ursprünglicher Ansatz sollte zB so funktionieren:

    int MyStrCmp (char str[], char str2[])
    {
        int a = 0;
        while (str[a] == str2[a] && str[a] && str2[a])
            a++;
        return str[a] - str2[a];
    }
    

    (ungetestet)



  • Falls du einmal einen K&R in die Finger bekommst, kannst du das ganze auch in Kapitel 5.5 nachlesen. Die Halbgötter machen das dort übrigens sehr ähnlich zu deinem Ansatz:

    int strcmp(char *s, char *t)
    {
        for ( ; *s == *t; s++, t++)
            if (*s == '\0')
                return 0;
        return *s - *t;
    }
    

    Das zusätzliche if trifft nur zu, wenn in s und t gleichzeitig ein Nullbyte gefunden wird. In dem Fall geben sie, genau wie fricky, gleich Null zurück, ohne die Differenz von Null und Null zu berechnen.


Anmelden zum Antworten