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



  • Hey Leute.

    Habe unabsichtlich im C++ Teil meine Frage gestellt, die war aber anders als hier, weil drüben konnten sie mir noch weiter helfen.

    Jetzt habe ich ein anderes Problem mit dem selben Programm.

    Es wird nach dem 1. Zeichen abgebrochen zu vergleichen.
    Ist eine Fußgesteuerte Schleife die Lösung? Wenn ja, wie geht das? habe ich noch nie gemacht.

    do
    .
    .
    .
    while

    so vielleicht?

    Hier mein Code

    int MyStrCmp (char str[], char str2[])
    {
    
    int a;
    	a = 0;
    	while (str[a] == str2[a] || str[a] !=  '\0' || str2[a] !=  '\0')
    	{
    		if (str[a] > str2[a])
    		{
    			return 1;
    		}
    		if (str[a] < str2[a])
    		{
    			return -1;
    		}
    		if (str[a] == str2[a])
    		{
    			return 0;
    		}
    		a++;
    	}
    
    }
    

    Danke schon mal für die Hilfe.



    1. check mal deine while bedingung ( überlegen! )
    2. warum kann die do while nicht die lösung sein?


  • if (str[a] > str2[a])
            {
                return 1;
            }
            if (str[a] < str2[a])
            {
                return -1;
            }
            if (str[a] == str2[a])
            {
                return 0;
            }
    

    strcmp muss übrigens gar nicht 1 oder -1 zurückgeben, wenn die Strings nicht gleich sind. Der Standard verlangt nur eine positive/negative Zahl. Also kann man die 12 Zeilen kürzer und effizienter machen:

    return str[a] - str2[a];
    

    Das ist schon mal eine ordentliche Einsparung.

    Warum deine Funktion nach dem ersten Zeichen abbricht, verrate ich dir auch: nämlich wird bei jedem Schleifendurchlauf einer der drei if -Zweige zutreffen. Und in jedem steht ein return , deshalb wird die Funktion auch gleich wieder verlassen. Diese drei if -Zweige (oder besser meine Vereinfachung) musst du aber eigentlich erst dann einschalten, wenn du erkannt hast, das in den beiden strings nicht das gleiche Zeichen ist. Sonst kannst du einfach die nächsten beiden Zeichen vergleichen.

    Ist eine Fußgesteuerte Schleife die Lösung?

    Kann man sicher machen. Ich würde keine nehmen.

    EDIT:
    Schon wieder Silben verschluckt... 🙄



  • Ahh, verstehe.
    Es wird ja solange überprüft, bis die 2 Variablen gleich sind. Und in meinem Fall sind sie es gleich beim 1. mal, von daher hüpft er sofort aus der Schleife raus.

    Bei der Do While Schleife kommt das selbe bei raus.

    Wie kann ich dem Programm sagen, dass es weiter machen soll und nicht beim 1. mal abbrechen soll?



  • Ich bin mir nicht sicher, ob ich das klar genug rüber gebracht habe. Jedenfalls darfst du diese drei if-Zweige (oder besser meine Vereinfachung), nur einschalten, wenn str[a] nicht gleich str2[a] ist, also am einfachsten nach der Schleife; die wird nämlich verlassen, wenn dieser Fall eintritt:

    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.



  • mngbd schrieb:

    strcmp muss übrigens gar nicht 1 oder -1 zurückgeben, wenn die Strings nicht gleich sind. Der Standard verlangt nur eine positive/negative Zahl. Also kann man die 12 Zeilen kürzer und effizienter machen:

    return str[a] - str2[a];
    

    Das ist schon mal eine ordentliche Einsparung.

    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). also, auch wenn b<c<a ist gibts auch negativen bzw. positiven output. vielleicht reicht das ja schon (hauptsache 0 heisst 'ist gleich').
    🙂



  • Ähem, Fricky.

    Kannst Du Dir erklären warum Leute '\0' schreiben anstatt einfach 0 ?
    Das ist ja fast schon wieder Pascal ... 😃



  • Scheppertreiber schrieb:

    Kannst Du Dir erklären warum Leute '\0' schreiben anstatt einfach 0 ?

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



  • Jau. Das sind die geheimen Codes um Anfänger aus der Spur zu werfen.
    C ist eigentlich auch nur ein böses Spiel 😃 😃 😃



  • 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.
    🙂


Anmelden zum Antworten