[C]Zwei Arrays auf alphabetische reinfolge überprüfen

03/26/2015 21:29 #Saiirex#1
Hey, ich habe zwei Char Arrays die wie folgt aufgebaut sind:

Name Vorname Straße Hausnummer PLZ Ort

Ich möchte jetzt überprüfen welches Array im Alphabet zuerst dran kommt.

z.B. Name Müller und Kellner, dann sollte Kellner zu erst ausgegeben werden und dann Müller. Habt ihr ne Idee wie ich es lösen kann?
03/26/2015 21:41 Jeoni#2
Gibt für solche Fälle schon vorgefertigte Funktionen.
Schau dir mal [Only registered and activated users can see links. Click Here To Register...] an. In einigen Fällen gibt es auch eine Implementation von [Only registered and activated users can see links. Click Here To Register...], zum einfachen Vergleichen ohne beachten von Groß- und Kleinschreibung.
Alternativ kann man das ganze natürlich auch manuell implementieren, aber ich vermute mal, dass dir die Standardfunktionen reichen?!
Mit freundlichen Grüßen
Jeoni
03/26/2015 22:09 #Saiirex#3
Danke, das war ziemlich hilfreich. Weißt du vlt noch wie mein ein Chararray rückwärts liest? Also habe ich in einem Array z.B. Auto und möchte in ein anderen otuA (auto rücktwärts gelesen) reinschreiben?
03/26/2015 22:20 Jeoni#4
Müsste irgendwie so in der richtung gehen:
Code:
const char* src = "Auto";
size_t len = strlen(src);
char* dst = (char*)malloc(len + 1);
size_t i;

dst[len] = '\0'; // nulltermination
i = --len; // decrement len and initialize i for the loop below

do
{
 dst[len - i] = src[i];
}while(i--);
Hab's nicht getestet, aber so ca. sollte ja klar sein, was ich meine. Man kann's natürlich auch ohne Zählvariable, dafür mit Pointern machen, die man entsprechend inkrementiert / dekrementiert.
Mit freundlichen Grüßen
Jeoni
03/26/2015 22:26 #Saiirex#5
Irgendwie check ich bei dem Code gar nix ;D
03/26/2015 23:02 snow#6
In place:

Code:
void reverse(char *str)
{
	int len = strlen(str);
	for (int i = 0; i != len / 2; ++i)
	{
		char tmp = str[i];
		str[i] = str[len - 1 - i];
		str[len - 1 - i] = tmp;
	}   
}
Mit neuem String:

Code:
char* reverse(char *str)
{
	int len = strlen(str);
	char *r = (char *)malloc(len * sizeof(char) + 1);
	r[len] = '\0';
		
	for (int i = 0; i != len; ++i)
	{
		r[len - 1 - i] = str[i];		
	}	
	
	return r;
}
03/26/2015 23:06 dowhile#7
1. Zeile: Einfach nur einen neuen Zeiger der auf "Auto" zeigt, d.h. es gilt src[0] = 'A', src[1] = 'u', src[2] = 't', src[3] = 'o'. Verstehst du, wieso das gilt? Ein Array in C ist nichts anderes als ein Zeiger auf das erste Element des Arrays, und die anderen Elemente des Arrays liegen im Speicher direkt dahinter. Deswegen kannst du ein Array genau so behandeln wie ein Zeiger, und ein Zeiger genau so wie ein Array.

2. Zeile: len bekommt die Länge von src, also den Wert 4.

3. Zeile: Hier wird neuer Speicher reserviert. malloc nutzt du, um Speicher auf dem Heap zu reservieren. Dazu etwas: Du hast im Grunde zwei Speicherbereiche: Stack und Heap.
Wenn du innerhalb einer Funktion eine Variable anlegst, dann wird sie auf dem Stack gespeichert. Sobald die Funktion zu Ende ist, werden alle Variablen, die in ihr angelegt wurden, gelöscht. Genauer: Stell dir den Stack wie ein langes Band vor, auf das Werte gelegt werden können. Dazu gibt es einen Zeiger der auf das nächste freie Feld zeigt. Wird ein Wert darauf abgelegt, dann kommt der Wert also auf das Feld, auf den der Zeiger momentan zeigt, und er bewegt sich anschließend ein Feld nach vorne.
Wenn nun eine Funktion betreten wird, dann merkt sich dein Programm wo sich der Zeiger momentan befindet. Wird die Funktion beendet, dann wird der Zeiger einfach auf die gemerkte Position zurück gesetzt, sodass alle Werte, die während der Funktion aufs Band gelegt wurden, sich nun wieder im freien Bereich befinden.
Praktisch heißt das also: Legst du in einer Funktion eine lokale Variable an, und die Funktion ist vorbei, war es das auch mit der lokalen Variable. Deswegen funktioniert in C zum Beispiel folgendes auch nicht:
Code:
char *get_string(void) {
  char string[80];
  strcpy(string, "Hello world!");
  return string;
}

int main(int argc, char **argv) {
  printf("%s\n", get_string());
  return 0;
}
Denn: char string[80]; ist eine lokale Variable, also auf dem Band. get_string() liefert nun zwar den Zeiger auf den Anfang von unserem Text zurück, aber wir nutzen diesen Zeiger erst, nachdem die Funktion zu Ende ist. Der Zeiger zeigt also in den freien Bereich vom Stack-Band, und damit gibt es keine Garantie mehr, dass dort tatsächlich noch das liegt, was wir gerne haben wollen.

Weil manche Werte nun aber behalten möchte, wenn eine Funktion vorbei ist, gibt es den Heap, also ein zweites Band. Hier ist es völlig egal, wann wir uns dort Speicher holen, wann eine Funktion beginnt oder zu Ende ist. Wir reservieren manuell mit malloc() dort Speicher und geben ihn mit free() wieder frei. Von dort holt sich Jeoni in seinem Beispiel den Speicher, und zwar len + 1 Bytes, also fünf Bytes. Genau so viel brauchen wir, um das Ergebnis zu Speichern:
o, t, u, A, \0
Dabei soll \0 das Byte "0" sein und nicht das Zeichen "0". Das hängt an jedem String hinten dran, damit das Programm weiß, wann der String zu Ende ist. Deswegen benötigt ein String der Länge n auch immer n + 1 Bytes. Beachte, dass strlen() wirklich die Länge des Strings liefert, also nicht die Anzahl der Bytes, die du brauchst, um ihn zu speichern.

4. Zeile: Klar. Vielleicht nur: size_t ist oft ein Alias für unsigned int, der immer genutzt wird, man die Größe von einem Array speichern möchte.

5. Zeile: Das letzte Byte wird auf "0" gesetzt, um also zu zeigen, dass der String dort zu Ende ist.

Rest: i wird auf len - 1 = 3 und ebenso len auf len - 1 = 3 gesetzt. In der Schleife werden die einzelnen Bytes rüber kopiert, konkret so:
Code:
dst[0] = src[3] (len = 3, i = 3)
dst[1] = src[2] (len = 3, i = 2)
dst[2] = src[1] (len = 3, i = 1)
dst[3] = src[0] (len = 3, i = 0, Schleife terminiert)
Die Schleife terminiert, wenn i = 0 gilt, denn i ist die Bedingung: Jeder Zahlenwert ungleich Null entspricht in C wahr und nur der Zahlenwert Null entspricht falsch. Deswegen terminiert die Schleife also, wenn i Null ist. Wie du an den konkreten Werten nachvollziehen kannst, wird der String also in umgekehrter Reihenfolge nach dst kopiert.