Benötige Hilfe bei einem Programm: Vergleichen von Arrays



  • supertux schrieb:

    while(array1[i] != '\0') 
    { 
      printf("%c\n", array1[i]); 
      i++; 
    }
    

    An sich ist der Code nicht falsch, aber in der Regel nutzt man dafür eine for -Schleife

    Huh? Bitte ... huh?

    Ich bin der Erste in der Reihe, wenn es darum geht, auf die bekloppte NUL-Terminierung von C-Strings draufzuhauen - da braucht man dann einfach die Länge, die man mit strlen oder, bei Arrays, mit einem strlen_constant ermitteln kann:

    #define strlen_constant(string)  ((sizeof(string) / sizeof((string)[0])) - 1)
    

    Aber: wenn man immer mit NUL-terminierten Strings arbeitet, kann man sich das strlen auch einfach sparen. Damit erzeugt man nur nochmal einen Durchlauf des Strings. Nicht unnötig, aber unnötig so, wie der OP seine Arrays durchgeht.



  • Danke schon einmal für die Antworten.

    ich habe nun versucht die Lösung von Sepp J zu verfolgen. HierbeI habe ich noch einge Fragen ob mein code soweit richtig ist...

    In der Zeile 34 (erste Schleife) lege ich meine Startposition für den Suchstring (array2) fest.
    In der Zeile 36 (zweite Schliefe) lege ich die länge der Suchschleife fest. In der darauffolgenden If Abfrage möchte ich die Suchstring (Startposition+Suchlänge) mit dem Array1 vergliechen. Hierbei weiß ich jedoch nicht wie ich die versch. Arrayfelder bzw. längen der Arrays abfragen soll?

    array2[k+j]
    

    ist quatsch?!.
    Kann mir hier jemand weiterhelfen? Danke.

    # include <stdio.h>
    # include <string.h>
    # include <stdlib.h>
    
    #define MAX 45
    
    int main(void) 
    {
    
       	int i = 0;  //Variable im array1
       	int j = 0;  //Variable im array2 Suchlänge
       	int k = 0;  //Startpos.
    
      	char array1[MAX];
      	char array2[MAX];
      	char maske[45];
    
    	printf ("Kartenstring eingeben:\n");
    	fgets (array1, 42,stdin);
    
    	printf ("Ausgelesenerstring eingeben:\n");
    	fgets (array2, 42,stdin);
    
    	// hier wird der array1 zeichen für zeichen ausgegeben	
    	size_t len = strlen(array1);
    	for(i=0; i < len; ++i)
    	{
    	  printf("%c\n", array1[i]);
    	}
    
    	// suchschleife
    	size_t len2 = strlen(array2);   		 	 //ermitteln von länge array2
    	for(array2[k]; k = len2 ; k++)				 //von startpos. array2. immer ein Feld weiter springen. = startpos ändern
    	{
    			for(j=len2; j =1 ; j--)			 	 //schleife: von Gesamtlänge array2 bis länge =1 = suchlänge
    			{				
    				if(strstr (array1, array2[k+j]))  //suche string von startpos bis startpos+ suchlänge in array1.
    				printf("Beide Arrays haben %d uebereinstimmungen\n An der Stelle %d\n", j, k);
    				else
    				printf("Die Arrays sind unterschiedlich\n");
    			}	
    	}		 	
    }
    


  • Schau dir noch mal die richtige Verwendung der for-Schleifen an (insb. der 2. Parameter)!



  • Okay. Der 2.parameter sagt mir wann die for schleife beendet wird.
    Bei der suchschleife:
    1.for-Schleife ändere ich die startposition meines Sucharrays solange bis der Wert, der Länge meines arrays hat. (Ich ändere die startposition bis zum letzten Feld des suchArray).

    Bei der 2.for-Schleife ändere ich die Länge des sucharrays von der Max Länge des array2 bis herunter zu einem Feld des Arrays.
    Sehe ich das soweit richtig?

    Ich stelle mir nun immer noch die Frage wie ich die verschiedenen Längen und Startpunkte meines sucharrays mit dem Array1 vergleichen kann?

    Es wäre nett wenn mir hier jmd. Weiterhelfen könnte.

    Gruß



  • Wenn die Statements der for-Schleife mal einzeln geschrieben werden, was bewirken die?

    array2[k]; 
    k = len2;
    k++;
    
    j=len2; 
    j =1 ; 
    j--;
    

    (Schreib ruhig Kommentare dahinter)


  • Mod

    oschi619 schrieb:

    Okay. Der 2.parameter sagt mir wann die for schleife beendet wird.

    Schon falsch. Der zweite Ausdruck sagt, wann die Schleife läuft.



  • Hallo,
    ich habe im zweiten Parameter eine Zusweisung und keinen Vergleich...

    array2[k]; //initialisierung start bei k. int =0
    k = len2;  //hier mein fehler... sollte k<= len2 heißen: läuft so lange, solange k kleiner gleich len2 ist
    k++        // k bei jedem durchlauf um 1 hochzählen
    

    nun habe ich aber immer noch die Frage mit dem Vergleichsarray.

    array2[k+j];
    

    wie kann ich eine bestimmte läng von Feldern eines Arrays, mit einem anderen Array Vergleichen?

    Danke



  • array2[k]; // Code ohne Effekt. 
    k = len2;  // k bekommt den Inhalt (Wert) von len2. Das ist eine Zuweisung, kein Vergleich
    k++        // Nach dem Zugriff auf k, k um eins erhöhen
    

    Da spielt es keine Rolle, ob der Code in einer for-Anweisung steht.

    oschi619 schrieb:

    wie kann ich eine bestimmte läng von Feldern eines Arrays, mit einem anderen Array Vergleichen?

    Dafür gibt es memcmp oder, wenn es um Zeichenketten geht, strncmp (beachte das n in der Mitte)



  • nach diesen oder ähnlichen Funktionen habe ich bereits gegoogelt, jedoch nicht glücklich damit geworden.
    Mit memcmp kann ich jedoch nur die ertsen n Zeichen eines arrays vergliechen. Fällt raus da ich auch innerhalb eines Arrays Felder vergleichen möchte. Richtig?
    Mit strcmp kann ich zwar zwei arrays vergleichen. Ich weiß jedoch nicht wie ich z.B das 2 bis 5 feld eines arrays mit einem anderen vergleichen kann? 😕 😕


  • Mod

    oschi619 schrieb:

    Mit memcmp kann ich jedoch nur die ertsen n Zeichen eines arrays vergliechen. Fällt raus da ich auch innerhalb eines Arrays Felder vergleichen möchte. Richtig?
    Mit strcmp kann ich zwar zwei arrays vergleichen. Ich weiß jedoch nicht wie ich z.B das 2 bis 5 feld eines arrays mit einem anderen vergleichen kann? 😕 😕

    Du beschreibst zwei Mal das gleiche, aber bei einem Mal denkst du, es hilft dir, beim anderen Mal nicht? 😕

    All die Funktionen, die du beschrieben hast, nehmen Zeiger als Argumente, keine Arrays (in C können Arrays gar nicht direkt Funktionsargumente sein!). Ein Array ist kein physisches Konstrukt, das ist einfach nur eine Art und Weise, über Speicherbereiche nachzudenken, die dir beim Programmieren hilft. Die Funktionen strncmp und memcmp nehmen als Argumente zwei Zeiger und eine Länge und vergleichen dann die Speicherbereiche dahinter, egal ob du über diese Bereiche als Array denkst oder nicht.

    Weiterhin wird der Bezeichner eines Arrays innerhalb eines Ausdrucks (fast) immer als ein Zeiger auf sein erstes Element angesehen. Das heißt, du kannst Zeigerarithmetik damit machen (d.h. mit dem Zeiger rechnen).

    int array[1234];
    array;    // Dies ist ein Zeiger auf das erste Element des Arrays
    array + 1;  // Dies ist ein Zeiger auf ein Element weiter hinten, also das zweite
    array + 2;  // Das dritte Element
    // usw.
    

    Das darfst du natürlich auch als Argument für memcmp/strncmp benutzen.



  • oschi619 schrieb:

    nach diesen oder ähnlichen Funktionen habe ich bereits gegoogelt, jedoch nicht glücklich damit geworden.
    Mit memcmp kann ich jedoch nur die ertsen n Zeichen eines arrays vergliechen. Fällt raus da ich auch innerhalb eines Arrays Felder vergleichen möchte. Richtig?

    Falsch.
    Du kannst beliebige (dem Programm zugewiesene) Speicherbereiche damit vergleichen.
    Du musst halt nur die Anfangsadressen der Bereiche kennen.

    oschi619 schrieb:

    Mit strcmp kann ich zwar zwei arrays vergleichen. Ich weiß jedoch nicht wie ich z.B das 2 bis 5 feld eines arrays mit einem anderen vergleichen kann? 😕 😕

    strcmp hatte ich gar nicht vorgeschlagen.
    Das ist auch nicht für den Vergleich von Arrays gedacht.

    Ist dir der Unterschied zwischen einem Array und einem C-String bewußt?
    Daraus folgt dann auch der Unterschied zwischen memcmp und strncmp .



  • Danke erst mal für die Beiträge.
    Ich habe es nun noch einmal versucht, jedoch ohne wirklichen Erfolg.
    Mit strlen lese ich die Anzahl der Zeichen des Arrays aus + \n. Deshlab ziehe ich von der Anzahl jeweils eins ab? Richtig?
    Bei meinem Vergleich ab Zeile 42 funktioniert jedoch etwas nicht richtig.

    Vielleicht kann mir jemand weiter Helfen.

    Hier der Code

    # include <stdio.h>
    # include <string.h>
    # include <stdlib.h>
    
    #define MAX 45
    
    int main(void) 
    {
       	int i = 0;  //Variable im array1
       	int j = 0;  //Variable im array2 Suchlänge
       	int k = 0;  //Startpos.
    
      	char array1[MAX];
      	char array2[MAX];
      	char maske[MAX];
    
    	printf ("Kartenstring eingeben:\n");
    	fgets (array1, 42,stdin);
    
    	printf ("Ausgelesenerstring eingeben:\n");
    	fgets (array2, 42,stdin);
    
    	// hier wird der array1 zeichen für zeichen ausgegeben	
    	size_t len = strlen(array1);
    	printf("Array1 Anzahl Zeichen %d\n\n", len-1);								//ermitteln der länge array1???
    	for(i=0; i <= len-1; ++i)
    	{
    	  printf("%c", array1[i]);
    	}
    	printf("\n");
    
    	// hier wird der array2 zeichen für zeichen ausgegeben	
    	size_t len2 = strlen(array2);
    	printf("Array2 Anzahl Zeichen %d\n\n", len2-1);								//ermitteln der länge array2???
    	for(i=0; i <= len2-1; ++i)
    	{
    	  printf("%c", array2[i]);
    	}
    	printf("\n");
    
    	// suchschleife	
    	for(array2[k]; k <= len2-1 ; k++)				 	//von startpos. array2. immer ein Feld weiter springen. = startpos ändern
    	{
    			for(j=len2-1; j >=1 ; j--)			 		//schleife: von Gesamtlänge array2 bis länge=1 = suchlänge
    			{	
    				if(memcmp(array1, array2+k,j))			//vergliech array2 von startpos. k mit der länge j??
    				printf("Beide Arrays haben %d uebereinstimmungen\n An der Stelle %d\n", j, k);
    				else
    				printf("Die Arrays sind unterschiedlich\n");						
    			}
    			j=len2-1;									// j auf den richtigen Wert zurück setzen.
    	}
    	k=0;
    	return EXIT_SUCCESS;		 	
    }
    


  • oschi619 schrieb:

    Danke erst mal für die Beiträge.

    Hast du die auch durchgelesen und versucht zu verstehen.

    oschi619 schrieb:

    Ich habe es nun noch einmal versucht, jedoch ohne wirklichen Erfolg.

    Also nicht gelesen und/oder verstanden.

    oschi619 schrieb:

    Mit strlen lese ich die Anzahl der Zeichen des Arrays aus + \n. Deshlab ziehe ich von der Anzahl jeweils eins ab? Richtig?

    Es wäre einfacher, das '\n' (sofern vorhanden) aus dem String zu entfernen.

    oschi619 schrieb:

    Bei meinem Vergleich ab Zeile 42 funktioniert jedoch etwas nicht richtig.

    !. Du verglechst Strings. darum ist strncmp besser geeignet.
    2. Schau dir mal genau die Bedeutung vom Rückgabewert von memcmp/strncmp an
    3. Brauchst du drei Schleifen.
    4. kannst du erst am Ende aller Vergleiche sagen, dass keine Übereinstimmung gefunden wurde.



  • Hallo

    - ich habe die Beiträge durchgelesen, sonst würde ich nicht in dieses Forum schreiben.
    -Möglicherweise habe ich es nicht verstanden was geschrieben wurde, deshalb versuche ich über ein Forum eine Erklärung zu bekommen.
    - ich weiß leider nicht wie man '/n' aus einem String löscht. Ich denke an jedem Ende eines Strings steht '/n'?

    Nun habe ich memcmp mit strncmp ausgetauscht, da ich Zeichen von Strings vergleiche. Desweiteren habe ich mir die Rückgabewerte angeschaut und einen Vergleich auf == 0 vorgenommen.

    ja ich denke ich brauche 3 Schleifen. In der ersten wird die Startadresse verschoben, in der zweiten die Länge des Suchstrings und in der if Abfrage findet der letztliche Vergleich statt?
    Der Vergleich funktioniert jedoch noch nicht richtig.

    for(array2[k]; k <= len2-1 ; k++)				 	//von startpos. array2. immer ein Feld weiter springen. = startpos ändern
    	{
    			for(j=len2-1; j >=1 ; j--)			 		//schleife: von Gesamtlänge array2 bis länge=1 = suchlänge
    			{	
    				check=(strncmp(array1, array2+k,j));     //vergliech array2 von startpos. k mit der länge j??
    				if (check == 0)		
    				printf("Beide Arrays haben %d uebereinstimmungen\n An der Stelle %d\n", j, k);
    				else
    				printf("Die Arrays sind unterschiedlich\n");						
    			}
    			j=len2-1;									// j auf den richtigen Wert zurück setzen.
    	}
    


  • oschi619 schrieb:

    sonst würde ich nicht in dieses Forum schreiben.

    Diesem.

    oschi619 schrieb:

    ich weiß leider nicht wie man '/n' aus einem String löscht. Ich denke an jedem Ende eines Strings steht '/n'?

    Erstens: wenn schon, dann '\n'.
    Zweitens: hast du dein C-Buch überhaupt mal aufgeschlagen? Strings werden mit '\0' terminiert, nicht mit '\n'. fgets schreibt unter Umständen ein '\n' rein, sprich, wenn genug Speicher vorhanden war, um die Usereingabe zu verarbeiten.
    Drittens: Auf '\n' kannst du ja leicht prüfen. Und wenn du eh mit Längenbegrenzung arbeitest, subtrahierst du von der Stringlänge des Users einfach 1, das ist dann das "Löschen" von '\n'.
    Viertens: Codetags kannst du auch die Sprache übergeben, in der du schreibst.

    for(array2[k]; k <= len2-1 ; k++)
    

    Erstens: Was zur Hölle soll array2[k] im Initialisierungsteil?
    Zweitens: k <= len2-1 kannst du auch einfacher schreiben: k < len2
    Drittens: Von korrekter Einrückung hast du noch nie was gelesen, oder?

    oschi619 schrieb:

    ich brauche 3 Schleifen [...] und in der if Abfrage findet der letztliche Vergleich statt?

    Erstens.
    Zweitens: Du hast bereits die Länge der zu überprüfenden Bytes, den '\0'-Check in strncmp kannst du dir eigentlich sparen.
    Drittens: Du willst immer den längsten Substring haben, oder? Wo merkst du dir denn die Position davon? Und wo die Länge? Was, wenn du was längeres findest?



  • dachschaden schrieb:

    Strings werden mit "\0" terminiert

    Wenn du schon wegen dieses/diesem aufschreist*, dann würde ich hier auch mal Einspruch erheben wollen.

    Preisfrage: welchen Wert hat

    sizeof(s)
    

    , wenn folgender String gegeben ist?

    char s[] = "\0";
    

    Strings werden mit '\0' terminiert, "\0" ist eine "Doppelnull". Wenn jeder String durch einen String terminiert würde, müsste ja auch der Terminatorstring irgendwie terminiert werden durch einen Terminatorstring, welcher wieder einen Terminatorstring bräuchte, argh, Rekursion, Überlauf, gute Nacht!

    * nach meinem Sprachgefühl ist "dieses" hier durchaus auch richtig:
    in dieses Forum: betont das Ziel. Das, was geschrieben wird, landet in diesem Forum. (die andere Bedeutungsmöglichkeit: "dieses Forum, das anderswo referenziert wird (also ein anderes Forum)" ist wohl auszuschließen)

    in diesem Forum: betont, wo der Text geschrieben wird. Zum Beispiel im Editor meiner Wahl oder direkt hier im Forumseditor.

    -> de.etc.sprache.deutsch (wenn ich noch news lesen würde)



  • wob schrieb:

    Preisfrage: welchen Wert hat

    sizeof(s)
    

    , wenn folgender String gegeben ist?

    Ist das eine rhetorische Frage?

    wob schrieb:

    Strings werden mit '\0' terminiert, "\0" ist eine "Doppelnull". Wenn jeder String durch einen String terminiert würde, müsste ja auch der Terminatorstring irgendwie terminiert werden durch einen Terminatorstring

    Hier sieht der Compiler nur das Stringarray, nicht den Inhalt, packt die '\0' dazu, und fertig.
    Weil es nämlich wahrscheinlich Leute gibt, die sich auf das dazupacken des '\0' verlassen und im Grunde einfach nur ein Array haben wollen, in dem die letzten beiden Elemente den Wert 0 haben. Und den Platz muss der Compiler dann auch liefern.

    EDIT: Paragraph gelöscht.
    EDIT2: s#"#'#g



  • oschi619 schrieb:

    - ich habe die Beiträge durchgelesen, sonst würde ich nicht in dieses Forum schreiben.
    -Möglicherweise habe ich es nicht verstanden was geschrieben wurde, deshalb versuche ich über ein Forum eine Erklärung zu bekommen.

    Nochmal:
    Was meinst du macht die Anweisung array2[k] in deiner ersten for-Schleife?
    Die Antwort hatte ich schon gegeben.

    oschi619 schrieb:

    - ich weiß leider nicht wie man '/n' aus einem String löscht. Ich denke an jedem Ende eines Strings steht '/n'?

    Das ist ein '\n' (achte auf die Richtung des \ )
    Ein \ leitet eine Escapesequence ein.
    '\n' steht für Newline und ist der Zeilenvorschub (teilweise in Verbindung mit Wagenrücklauf)
    Ein C-String wird mit '\0' terminiert. Das Zeichen mit dem Wert 0 (s. ASCII)

    Zum löschen:
    fgets speichert das '\n' von der Entertaste mit im String ab. Wenn es nicht drin steht, sind noch mehr Zeichen für die Zeile im Eingabestrom.
    Da fgets aber nach dem '\n' das Einlesen abbricht, kann es nur das letzte Zeichen sein.

    Daher:
    Ist das letzte Zeichen ein '\n', dann ersetze es durch '\0'

    Du kannst das z.B. mit printf("<%s>\n", array1); sehen.
    Wenn die > hinter dem String steht, ist kein '\n' drin. Ist sie in einer neuen Zeile, ist das '\n' noch drin.

    Am Anfang ist es evtl. besser auf Eingaben zu verzichten und die Strings direkt im Code abzulegen.

    @dachschaden
    Der Unterschied zwischen " und ' ist in C sehr groß und wichtig.
    Darum sollte man Anfänger nicht verwirren.



  • hmm.. du hast 2 Array mit "Zeichen" drin, willst du nun die arrays einfach nur vergleichen?

    Oder schaun bis zu welchem index die Zeichen der beiden array identisch sind oder wie was .. !?

    oder ist in array2 ein "teil-string" der in array1 gesucht wird?

    ich raffs nich.. p.s. ok ich habs auch nich von anfang an gelesen.. zu faul^^



  • @DirkB
    Mit array2[k] versuche ich meinen Startpunkt des zweiten Arrays zu versetzten jeweils ein Feld nach hinten. Sodass ich am Anfang vom ersten Feld an alle Felder vergleiche, wenn von dort aus die zweite Abfrage durchlaufen ist, möchte ich ein Feld weiter springen und dann wieder die zweite if-Abfrage durchlaufen usw.
    Dies funktioniert jedoch nicht, das sehe ich an meiner Ausgabe 😕 .

    das \n habe ich nun durch \0 ersetzt und bekomme so die korrekte Anzahl an Feldern angezeigt.

    Mein Vergleich mit den If Abfragen funktioniert jedoch immer noch nicht, wie ich mir das vorstelle.
    Kann es sein das ich die Anfangsposition von Array1 auch noch in einer Schleife verschieben muss um wirklich alle Zeichen miteinander zu vergleichen?

    for(array2[k]; k <= len2 ; k++)				 	//von startpos. array2. immer ein Feld weiter springen. = startpos ändern
    	{
    		printf("%c",array2[k]);
    			for(j=len2; j >=1 ; j--)			 		//schleife: von Gesamtlänge array2 bis länge=1 = suchlänge
    			{	
    				check=(strncmp(array1, array2+k,j));     //vergliech array2 von startpos. k mit der länge j??
    				if (check == 0)		
    				printf("Beide Arrays haben %d uebereinstimmungen\n An der Stelle %d\n", j, k);
    				else
    				printf("Die Arrays sind unterschiedlich\n");						
    			}
    			j=len;									// j auf den richtigen Wert zurück setzen.
    	}
    

Anmelden zum Antworten