C Vergleich zweier Zeichenketten

  • Ersteller Ersteller Taxotic
  • Erstellt am Erstellt am
T

Taxotic

Gast
Hi,

wenn ich die Funktion strcmp(s1,s2) anwende, sollten eigentlich zwei strings verglichen werden. Sollten diese übereinstimmen gibts 0 als Rückgabewert.

In meinem Programm werden Wörter umgedreht, und anschließend getestet ob sie übereinstimmen.

Bsp: hallo -> ollah stimmt nicht überein
rentner ->rentner stimmt überein

Nach dem Vertauschen lasse ich die beiden Zeichenketten "hilf" und "wort" ausgeben, auch wenn sie übereinstimmen wird in der Vergleichsfunktion kein 0 zurückgegeben.

Hat das vielleicht etwas mit dem /0 zutun?

Danke für eure Hilfe!

Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 

int main()
{
	int i,j;
	char *hilf;
	char wort[20];
	printf("Wort\n");
	fgets(wort, 20, stdin);
	hilf = (char *) malloc (strlen(wort)* sizeof(char));

	for (i=0, j=strlen(wort)-1; i<=strlen(wort)-1, j>=0; i++, j--)

		{
			hilf[j]=wort[i];
			hilf[strlen(wort)]='\0';
		}

	printf("%s",wort);
	printf("\n%s",hilf);


	if (strcmp(wort, hilf)==0)
		     printf("\n ja!");
	else      
                     printf("\n No!");

	return 0;
}
 
Es liegt nicht am \0, sondern daran, dass das von der Eingabetaste ausgelöste Zeilenendezeichen (etwa \n in Linux) ebenfalls in der Variable wort landet. Du hast dann:

wort: rentner\n
hilf: \nrentner

die offensichtlich verschieden sind. Du musst also das \n vorher entfernen.
 
ja , kann wohl sein.

sonst mach doch einfach

while (!= "\n"){
j++;
i++;
.........

zusätzlich kannst du erstmal um den Fehler zu finden, jeden Buchstaben der beiden Zeichenketten einzeln ausgeben.
 
Bei mir funktioniert es (mit gcc 4.6.3), wenn ich den fgets()-Aufruf ersetze durch
Code:
scanf("%20s", wort);
 
Vielleicht noch ein genereller Tipp:

Benutze Single-Step-Funktionen deines Debuggers und schau die schrittweise an wie sich deine Variableninhalte verändern. Das geht bei einem so überschaubaren Problem wie dem hier geschilderten deutlich schneller, als einen Post im Forum zu verfassen und auf die Antworten zu warten.

j o e
 
Und wenn du schon Speicher per malloc() allokierst solltest du ihn am Ende auch wieder mit free() freigeben ;)
 
Also ob der Speicher nun am Ende der main freigegeben wird oder nicht macht keinen Unterschied...
Schlimmer find ich, dass nicht mal geprüft wird, ob der Zeiger überhaupt gültig ist...
 
Auch ist der Cast überflüssig und sizeof(char) immer 1.
 
Du musst auch Speicher für \0 reservieren. Sonst schreibt er das dahinter obwohl der Speicher vielleicht wem anders gehört.
 
Nein. Denn das mit eingelesene \n wird bei strlen() mitgezählt und später durch ein \0 ersetzt. (Sofern er es richtig macht.)
 
1668mib schrieb:
Also ob der Speicher nun am Ende der main freigegeben wird oder nicht macht keinen Unterschied...
Schlimmer find ich, dass nicht mal geprüft wird, ob der Zeiger überhaupt gültig ist...

Ähm sicher? C hat wohl kaum eine Garbage Collection. Natürlich gibt das Betriebssystem den Speicher wieder frei, sobald das Programm beendet wurde. Läuft das Programm allerdings länger (z.B. wenn es ein Server ist), dann wird immer mehr Speicher verloren gehen und das Programm immer mehr Speicher benötigen.

Klar bei diesem kleinen Programm kann man drauf vertrauen, dass das Betriebssystem danach um die Sache kümmert, aber good practice ist das keinesfalls. Und einem Anfänger zu raten, dass er free() auch weglassen kann ist wohl das schlechteste überhaupt.
 
@stwe: Ja sicher, am Ende des Programms wird sämtlicher vom Programm allokierter Speicher freigegeben... Das hat gar nichts mit einem Garbage Collector zu tun (Der Garbage Collector hat ja auch nicht die Aufgabe, am Ende alles freizugeben, sondern ungenutzte Elemente schon während der Laufzeit... um am Programmende alles freizugeben, braucht man kein Buch zu führen, was noch genutzt wird und was nicht, schließlich wird "nichts" mehr genutzt...).
Es soll ja sogar Programme geben, die stürzen ab. Da räumt auch nichts mehr auf, aber das Betriebssystem gibt halt den Speicher frei... So ein Absturz kann übrigens passieren, wenn man Zeiger vor der Benutzung nicht auf Gültigkeit prüft. Das stört hier aber keinen. Und wenn du mir jetzt noch sagst, wo ich rate, das free wegzulassen, dann geb ich dir nen Bier aus. Ich find nur das Rumgeheule deswegen sinnlos. Da werden Dinge kritisiert, die keinerlei Relevanz in dieser Situation haben.


Im Übrigen: Dass man so ein Palindromtester auch viel eleganter schreiben könnte, ist eigentlich egal... da spart man sich die sinnlosen dynamischen Speicherangelengeheiten eh... Verwenden von dynamischen Speicher ohne Grund ist für mich auch keine good practice...
Code:
int isPalindrom(char line[])
{
	int i;
	int length;

	length = strlen(line);
	
	/* Es reicht nur bis zur Mitte zu durchsuchen,
	 * wenn die Länge ungerade ist spielt das
	 * mittlere Zeichen keine Rolle mehr (z.B. uhu)
	 */
	for (i = 0; i < length / 2; i++) {
		/* das i-te Zeichen mit dem i-ten Zeichen von
		 * hinten (= [Länge - 1] - i) vergleichen,
		 * wenn sie verschieden sind die Funktion
		 * mit Rückgabewert 0 verlassen
		 */
		if (line[i] != line[length-1-i]) {
			return 0;
		}
	}

	/* alle Vergleiche waren erfolgreich, also
	 * muss es sich um ein Palindrom handeln.
	 */
	return 1;
}
 
Zuletzt bearbeitet:
Du hast geschrieben
Also ob der Speicher nun am Ende der main freigegeben wird oder nicht macht keinen Unterschied...
Du hast nicht geschrieben "bei diesem Problem" o.Ä. Man könnte das auch so verstehen, dass es generell keinen Unterschied macht, ob man Speicher freigibt oder nicht. Und das ist halt falsch.

Natürlich räumt das OS hinter meinem Programm her, aber es ist halt bad practice Speicher nicht wieder freizugeben, v.a. wenn mans dann auch nicht macht, wenn das Programm nicht sofort beendet wird sondern länger läuft.
 
@stwe: Naja ob Speicher "am Ende" freigegeben wird (was für mich Porgrammende bedeutet) ist für mich schon ne generelle Aussage. Und es ist nicht mal zwingend das OS, das aufräumt. Wenn z.B. malloc Speicher auf dem Heap holt, dann bekommt das OS davon gar nichts mit...

Und ein Programm, das länger läuft, hat für mich kein Ende...

Im Übrigen hab ich ja auch sogar noch kritisiert, überhaupt dynamischen Speicher zu verwenden, weil es an sich keine Notwendigkeit hat hier und viel elegantere Lösungen gibt...
 
Zuletzt bearbeitet:
Natürlich liegt es am OS. Das OS "merkt" sich, welcher Prozess welchen Speicher reserviert und löscht diesen, sobald der Prozess beendet wird.
Aber das ist nur bei modernen Betriebssystemen so. Wenn man mal nicht für das neuste Windows o.ä. programmiert, kann es sein, dass nach 1000 Programmaufrufen plötzlich der Speicher voll ist.
 
@Wurstinator: Gerade bei nicht-modernen Betriebssystemen bekommt das OS häufig gar nix vom malloc mit, weil die Programme ihre eigene Speicherverwaltung haben... dort wird beim Programmstart Speicher allokiert und in Heap und Stack usw aufgeteilt und wenn dann der Speicher nicht reicht, kommt der bekannte Heap-Overflow...

Und was heißt für dich "1000 Programmaufrufen"? Ich starte 1000 Mal das Programm und es wird 1000 Mal beendet, und ich mach 1000 Mal am Ende kein free? Zeig mir bitte ein Beispielprogramm und nenn mir das entsprechende OS, bei dem das Probleme macht.
 
Zurück
Oben