C - In einer Datei Personen mit einer bestimmten Postleitzahl herausfiltern/ausgeben

elektro2

Cadet 4th Year
Registriert
Feb. 2014
Beiträge
67
Hallo liebes Forum!

Ich hätte gerne Lösungsvorschläge für folgendes Problem.

In der Datei data.txt sind verschiedene Personen mit Postleitzahlen aufgelistet. z.B.

Markus 77898
Tim 55767
Phil 42103
Tom 42103
Max 97732
Jonas 42103

Ich habe die Datei eingelesen in den String buf. Nun würde ich gerne alle Personen herausfiltern, die die PLZ
42103 haben. Ich habe schon darüber nachgedacht, die Streams irgendwie mit strcpy zu vergleichen. Leider ohne Erfolg.

Habt ihr irgendwelche Lösungsvorschläge?:)

Danke schonmal im Voraus :)


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


int main (void)
{
    char buf[1024];
    FILE *file;
    
    if ((file = fopen ("data.txt", "r")) == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    
    do {
        
        fgets(buf, 1024, file);
            
        
    }while(!feof(file));
    
    int plz[]={4,2,1,0,3};
    
    
    
    fclose(file);
    
}
 
Zuletzt bearbeitet:
String-Vergleiche macht man in C mit strcmp(), nicht mit strcpy().

Du legst in Zeile 22 deine Vergleichs-PLZ als Integer-Array an. Wenn du einen String-Vergleich möchtest, kannst du sie doch gleich als Character-Array anlegen:

Code:
const char plz[] = "42103";

P.S. Natürlich müßtest du noch jede eingelesene Zeile parsen und dann aufteilen in den Teil, der den Namen enthält und den Teil, der die eigentliche PLZ darstellt, und dann nur den letzten Teil mit der Vergleichs-PLZ vergleichen.
 
Hey.. . das mit dem parsen habe ich auch gerade gemerkt :)

ist für mich als c Anfänger noch relativ kompliziert. Ich habe die Funktion strtok gefunden. Damit könnte ich vielleicht parsen, wenn ein Leerzeichen auftritt. Aber irgendwie scheint die Lösung nicht wirklich elegant.
Komme einfach nicht weiter -.-
 
Wenn du weißt, dass tatsächlich jede Zeile so aussieht, kannst du die Datei auch (mit Pattern-Matching) in ein zweidimensionales Array einlesen (je char für Namen und int für PLZ). Dann suchst du eine bestimmte PLZ und weißt, dass der Name an gleicher Position steht.
 
Wenn immer das Muster «Name» «Leerzeichen» «Postleitzahl» «Zeilenumbruch» ist, kannst dir das zur Hilfe nehmen.
Parse je die Zeile bis zum Zeilenumbruch (\n) in ein temporäres char[]-Feld und vergleiche die letzten fünf Zahlen mit den gesuchten. Falls ein Treffer vorliegt, gibst du die Zeichen/den Namen aus (Position des Leerzeichen -1). Das wiederholst du dann für jede Zeile. Musst natürlich noch die Abbruchbedingung beachten.
 
Also mit dem ersten array klappt es. aber jetzt kann ich ja nicht nochmal von vorne anfangen, sonst bekommen ja alles Arrays den gleichen Inhalt
bin irgendwie überfordert^^
Das Problem ist eh, dass man eigentlich vorher ja nicht weiß , wieviel arrays man braucht.


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


int main (void)
{
    char buf[1024];
    FILE *file;
    
    if ((file = fopen ("data.txt", "r")) == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    
    do {
        
        fgets(buf, 1024, file);
            
        
    }while(!feof(file));
    
    
    const char plz[] = "42103";
    
    
    unsigned long laenge=strlen(buf);
    
    char array1[100];
    char array2[100];
    char array3[100];
    char array4[100];
    char array5[100];
    
    int i;
    
    for(i=0;i<laenge;i++)
    {
        
        while(buf[i]!='\n')
        {
            array1[i]=buf[i];
            
            
        }
        
    }
        
    

    
    fclose(file);
    return 0;
    
}
 
Zuletzt bearbeitet:
Genau, wenn du nicht weißt, wie viele ints du brauchst, nimmst du ein Array von ints. Und wenn du nicht weißt, wie viele Arrays du brauchst, nimmst du... ein Array von Arrays. :)
Oder wenn es für dich einfacher ist, zwei Arrays. In einem die PLZ, im anderen die Namen. Wenn du eine PLZ in plzArray[x] hast, steht der Name in nameArray[x].
 
Wenn man von irgendwas nicht weiß, wie viel kommt und dann ein Array nimmt, ist das ein Erfolgsrezept für eine Katastrophe. Erzählt dem Mann doch nicht so einen Mist, der glaubt das noch!

Die richtige Lösung wäre natürlich dynamische Allokierung, aber das kann man kaum erschöpfend in einem knappen Forenpost abhandeln und auch da haben kleine Fehler gravierende Folgen.
 
Zuletzt bearbeitet:
Für den Anfang ist es eine ausreichende Variante. Es ist ja nicht so, dass man überhaupt nicht weiß, wie viele Zeilen die Datei hat. Nur wenn da jetzt ein paar mehr oder weniger werden, ist ein Array gut genug. Andere Konzepte lernt man später.
 
powerfx: Du bist eine Gefahr für OP und jeden anderen, der das im Überfliegen liest. Man bringt ein Konzept nicht erst so falsch bei, dass der belehrte genug Seil bekommt, sich selbst aufzuhängen und sagt dann später ach ja übrigens, das geht eigentlich völlig anders. Vor allem, wenn man damit rechnen muss, dass es zu der zweiten Begegnung niemals kommen wird.
 
Ich bringe gar nichts bei, mit Arrays habe nicht ich angefangen. Wenn man die ganze Datei nicht in einen String speichern muss, sondern wirklich nur die Personen ausgeben will, dann braucht man auch keine Arrays.
Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
	FILE *datei = fopen("data.txt", "r");
	int plz, match = 0;
	char name[42];

	if(argc < 2)
	{
		fprintf(stderr, "Verwendung : %s <PLZ>\n", *argv);
		return EXIT_FAILURE;
	}

	if (datei != NULL)
	{
		while((fscanf(datei,"%s %d\n",name,&plz)) != EOF)
			if (atoi(argv[1]) == plz)
			{
				match = 1;
				fprintf(stdout,"%d: %s\n",plz,name);
			}
		fclose(datei);
		if (match == 0)
			fprintf(stdout,"Nichts gefunden.\n");
	}
	else
	{
		printf("\nDatei kann nicht geoeffnet werden.\n\n");
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Deine Lösung ist natürlich besser, leider ist sie unsichtbar.
 
Hi zurück :)

kann es nicht sein, dass fgets das problem darstellt? Vielleicht gibt es ja andere Möglichkeiten, als den ganzen Inhalt der Datei in
einem Array zu speichern. Es muss doch möglich sein, mit Irgendwelchen C Funktionen für Dateien , nach einem String zu suchen, dann
den Namen davor auszugeben, und den "Cursor " dann ans Ende der ersten PLZ setzen und weiter suchen usw...

Da muss es doch irgendwas geben -.-
 
powerfx schrieb:
Wenn man die ganze Datei nicht in einen String speichern muss, sondern wirklich nur die Personen ausgeben will, dann braucht man auch keine Arrays.

Ich will jetzt nicht pedantisch sein ... aber als was würdest du das hier bezeichnen:

Code:
char name[42];

? :p
 
Als Randbedingung ist auf jeden Fall gegeben, dass jede Zeile genau so aussieht, die PLZ nur aus Werten von 0-9 besteht und jede Zeile durch ein backslash n abgegrenzt ist. Suche immer noch nach einer geeigneten Lösung :) .
 
Deine Lösung ist natürlich besser, leider ist sie unsichtbar.

Mit dem Wissen, dass es seine aktuelle Verständnisfähigkeit überschreiten würde auf die Ausformulierung einer konkreten Lösung zu verzichten und das vernünftig zu begründen, sehe ich weiterhin als die bessere Antwort an. Vor allem, wenn ich meinen Post hiermit vergleiche:

Code:
char name[42];
[...]
fscanf(datei,"%s %d\n",name,&plz)

Die anderen kleinen Dummheiten lasse ich unkommentiert. Habe schon genug Verwarnungspunkte.
 
antred schrieb:
Ich will jetzt nicht pedantisch sein ... aber als was würdest du das hier bezeichnen:

Code:
char name[42];

? :p
Das ist ein String. ;)

elektro2 schrieb:
Als Randbedingung ist auf jeden Fall gegeben, dass jede Zeile genau so aussieht, die PLZ nur aus Werten von 0-9 besteht und jede Zeile durch ein backslash n abgegrenzt ist. Suche immer noch nach einer geeigneten Lösung :) .
Was willst du denn genau machen? Ist mir irgendwie noch nicht ganz klar, bzw. was gefällt dir an #11 nicht?

asdfman schrieb:
Mit dem Wissen, dass es seine aktuelle Verständnisfähigkeit überschreiten würde auf die Ausformulierung einer konkreten Lösung zu verzichten und das vernünftig zu begründen, sehe ich weiterhin als die bessere Antwort an.
Also "Sorry, das schaffst du nicht." oder wie?

asdfman schrieb:
Habe schon genug Verwarnungspunkte.
Vielleicht aus gutem Grund. Deine Kritik ist stets destruktiv und das ist für ein Forum nicht hilfreich.
 
Wie meine Antwort lautete, kannst du ja nachlesen. Die muss ich jetzt nicht wiederholen, oder?

Und mir vom Buffer-Overflow-Instructor Destruktivität vorwerfen zu lassen, kann ich mir leider nicht zu Herzen nehmen. Es spricht Bände, dass du den Kern jeder Kritik an dir (nicht nur von meiner Seite) abwinkst oder schlicht ignorierst oder einfach mit Nebensächlichkeiten abzulenken versuchst.
 
Achso, ok, du hattest es später noch editiert. Tja, also doch "Es ist leider zu kompliziert und dauert zu lange es zu erklären."
Eine solche Antwort ist nun mal nicht sehr hilfreich.
 
Mensch Leute, habt ihr nicht mehr zu tun als euch gegenseitig niederzumachen?
Dem Threadersteller ist hiermit überhaupt nicht geholfen.

Ich würde ja gerne helfen, wenn das aber der Dank ist, dann lasse ich das mal lieber... :rolleyes:
 
Die Aufgabe ist aus einer alten Informatik-Klausur für Elektrotechniker ( " Leichtere Informatik ")
Für die Aufgabe hat man ca. 15 Minuten Zeit.

Ich glaube nicht daran, dass die Lösung sehr viele Codezeilen erfordert. Dennoch komme ich nicht zum Ziel -.-
 
Zurück
Oben