fußballstatistik auswerten

S

soso

Jungspund
Hallo!

wir haben hier ein programm, was eine textdatei (spezielle tabelle) einlesen und verarbeiten können soll...

in dieser speziellen datei sind fußballergebnisse zu sehen... drei beispielzeilen:

PHP:
GER	KLOSE	5	1	12	8
ARG	CRESPO	3	1	5	2
BRA	RONALDO	3	1	8	7

es steht immer erst das länderkürzel, dann der spielername, dann die anzahl der tore, dann die der vorlgen, der torschüsse und der fehlschüsse...

das programm funktioniert soweit ganz gut, allerdings gibt es noch einen segmentation fault in der funktion "int statistik_mannschaft(char *name, struct listelement *start)"...

wenn wir einen falschen namen (z.b. BAR) eingeben, wird brav "Keine mannschaft hat diesen namen" ausgegeben, aber sonst gehts halt nicht (wenn wir BRA eingeben, kommt nur die meldung segmentation fault)...

sieht da jemand, wo das problem liegt???
wäre nett, wenn ihr uns helfen könnt....

hier mal noch unser programm^^
und keine angst... es ist zwar lang, aber es geht ja auch eigentlich nur um die funktion "int statistik_mannschaft(char *name, struct listelement *start)"...^^
also bitte trotzdem mal anschaun^^....
brauchen doch hiiiiilfe

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



/* Eine Struktur (bzw. Datentyp) namens SPIELER wird erstellt; sie enthält alle Infos zu einem Spieler */
typedef struct 			
{
	char Laenderkuerzel[4];		/* das Länderkürzel besteht aus 3 Zeichen und \0 */
	char Spielername[25];		/* ein Spielername besteht aus maximal 25 Zeichen */
	int Tore;
	int Vorlagen;
	int Torschuesse;
	int Fehlschuesse;	
}
SPIELER;



/* stellt eine einfach verkettete Liste von SPIELER-Strukturen dar
 * d.h. sie enthält einen Zeiger auf eine SPILER-Struktur und einen Zeiger auf die nachfolgende listelement-Struktur */
struct listelement
{
	SPIELER *spieler;
	struct listelement *next;
};



/* Gibt die übergebene SPIELER-Struktur auf dem Bildschirm aus.
 * Argument: spieler - die auszugebenede SPIELER-Struktur.*/

void spieler_ausgeben (SPIELER *spieler)
{
printf("%s (%s): %d Tor/e, %d Vorlage/n. %d Torschuss/schuesse, %d Fehlschuss/schuesse\n", spieler->Spielername, spieler->Laenderkuerzel, spieler->Tore, spieler->Vorlagen, spieler->Torschuesse, spieler->Fehlschuesse);
}



/* Liest die einzelnen Spieler zeilenweise ein und erzeugt für jeden
 * Spieler eine neue SPIELER-Struktur. Diese Strukturen werden als eine
 * verkettete Liste verknüpft.
 * Rückgabewert: Zeiger auf den Beginn der Liste. */

struct listelement *spieler_einlesen ()
{
 struct listelement *first = NULL, *zwischen = NULL, *einlist = NULL;
 SPIELER *spi;
 char Laenderkuerzel1[4];
 char Spielername1[25];
 int Tore1, Vorlagen1, Torschuesse1, Fehlschuesse1;
 while (scanf("%3s %24s %d %d %d %d", Laenderkuerzel1, Spielername1, &Tore1, &Vorlagen1, &Torschuesse1, &Fehlschuesse1) == 6)
 {
 spi = malloc(sizeof(SPIELER));			/* Speicherplatz für spi wird reserviert */
 strcpy (spi->Laenderkuerzel, Laenderkuerzel1);
 strcpy (spi->Spielername, Spielername1);
 spi->Tore = Tore1;
 spi->Vorlagen = Vorlagen1;
 spi->Torschuesse = Torschuesse1;
 spi->Fehlschuesse = Fehlschuesse1;
 einlist=malloc(sizeof(struct listelement));	/* Speicherplatz für einlist wird reserviert */
 einlist->spieler = spi;
 if (!first) first = einlist;
 if (zwischen) zwischen->next = einlist;
 zwischen = einlist;
 }	
 return first;
}



/* Gibt alle Spieler mit dem übergebenen Namen, die in der übergebenen
 * Liste enthalten sind, auf dem Bildschirm aus.
 * Argumente: name - Der gesuchte Name
 *            start - Zeiger auf den Beginn der verketteten Liste 
 * Rückgabewert: 1 falls (mindestens) ein Spieler gefunden wurde,
 *               sonst 0 */

int alle_spieler(char *name, struct listelement *start)
{     
	int gefunden = 0;	
	while(start)		/* solang start nicht 0 */
	{
	 if (strcmp(start->spieler->Spielername,name)==0) {spieler_ausgeben(start->spieler); gefunden = 1;}
	 start=start->next;
	}
	if (gefunden==0) printf("Kein Spieler hat diesen Namen.\n");
	return gefunden;
}



/* Gibt eine zusammenfassende Statistik für die übergebene Mannschaft 
 * aus. Diese ergibt sich aus allen in der übergebenen Liste 
 * gespeicherten Spielern mit dem passenden Mannschaftskürzel.
 * Argumente: name - das Mannschaftskürzel
 *            start - Zeiger auf den Beginn der verketteten Liste
 * Rückgabewert: 1 falls Spieler dieser Mannschaft in der Liste
 *               vorkommen, sonst 0 */

int statistik_mannschaft(char *name, struct listelement *start)
{
	int gefunden = 0;
	int ToreM = 0;
	float TorschuesseM = 0;
	float FehlschuesseM = 0;
	float Torschussquote, Torschuss, Fehlschuss;
	while(start != 0)
	{
	 if (strcmp(start->spieler->Laenderkuerzel,name) == 0)	/* vergleicht vorgegebenen Namen mit Namen in der Liste */
								/* wenn diese gleich sind, kommt 0 raus */
	 {
	  Torschuss = start->spieler->Torschuesse;
	  Fehlschuss = start->spieler->Fehlschuesse;
	  ToreM = ToreM + start->spieler->Tore;
	  TorschuesseM = TorschuesseM + Torschuss;
	  FehlschuesseM = FehlschuesseM + Fehlschuss;
	  gefunden = 1;
	 }
	 start=start->next;
	}
	if (gefunden == 1)
	{
	 Torschussquote = TorschuesseM / (TorschuesseM + FehlschuesseM);
	 printf("Statistik für %s:\n%d Tore, %lf Torschüsse (%lf Prozent Torschussquote)\n", start->spieler->Laenderkuerzel, ToreM, TorschuesseM, Torschussquote);
	}
	else printf("Keine Mannschaft hat diesen Namen.\n");
	return gefunden;
}



/* Das Programm kann mit einem oder zwei Kommandozeilenargumenten 
 * aufgerufen werden. Zuerst liest es die Spielerliste von der 
 * Standardeingabe (die normalerweise mit "<" aus einer Datei stammt).
 * Bei einem Argument wird dieses als Spielername interpretiert und 
 * alle_spieler aufgerufen. Bei zwei Argumenten muss das erste "-m" 
 * lauten, das zweite Argument wird als Mannschaftskürzel interpretiert
 * und an statistik_mannschaft übergeben. 
 * Bei einem falschen Aufruf wird der korrekte Aufruf auf dem
 * Bildschirm ausgegeben.
 * Der Fehlercode des Programmes ist 0 bei erfolgreicher Ausführung
 * (korrekter Aufruf, es wurden Spieler/Mannschaft gefunden), sonst 1.
 */

int main(int argc, char **argv)
{
	struct listelement *start;
	int erfolgreich;
	start = spieler_einlesen();
	if (argc==2)
	{ /*1 Argument --> Spielername angegeben*/
		erfolgreich=alle_spieler(argv[1],start);
		if (erfolgreich) /*Fehlercode entsprechend setzen.*/
			return EXIT_SUCCESS;
		else
			return EXIT_FAILURE;
	}
	if (argc==3 && argv[1][0]=='-' && argv[1][1]=='m' && argv[1][2]=='\0') 
	{ /* 2 Argumente (1.: "-m") --> Mannschaftsstatistik */
		erfolgreich=statistik_mannschaft(argv[2],start);
		if (erfolgreich) /*Fehlercode entsprechend setzen.*/
			return EXIT_SUCCESS;
		else
			return EXIT_FAILURE;
	} 
	/*--> falscher Aufruf */
	printf("Aufruf:\n");
	printf("%s Spielername\n",argv[0]);
	printf("%s -m Land\n",argv[0]);	
	return EXIT_FAILURE;
}

vielen dank
lg
 
Lass das Programm doch mal durch gdb laufen- dann bekommst Du die Zeilennummer, in der die Speicherschutzverletzung stattfindet.
Einfach 'gdb /Pfad/zum/Programm' eingeben, und 'run' tippen. Falls das Programm Optionen nimmt, diese vor 'run' mit 'set args' setzen.

Bei so vielen malloc's ist es nicht verwunderlich, dass sich ein Fehler einschleicht. Wenn man das macht (vorausgesetzt, ich habe es richtig bedient), so bekommt man heraus, dass 'spieler' in der Ausgabe in Zeile 127 nicht initiiert ist.
Dort koennt Ihr nun weitersuchen, weshalb nicht.

P.S.: verwendet besser strncmp und strncpy usw.! das ist sicherer. Ausserdem bleibt in Zeile 57 der Wert Laenderkuerzel[3] undefiniert, auch so etwas fuehrt schnell zu Programmfehlern. Lieber mit calloc statt mit malloc arbeiten!
 
Naja, wenn man beim Auswerten der Daten solange in der while-Schleife bleibt, bis start = 0 ist, braucht man sich nicht zu wundern, wenn in Zeile 127 start dann immer noch diesen Wert hat, und daher auf nichts sinnvolles mehr zeigt ;-)
 
Vielen vielen Dank!!!
Programm läuft jetzt...
war ja ein dämlicher fehler ...:trash:
ciao :winke:
 

Ähnliche Themen

Unix Webserver mit HTML Seite erstellen

GCC liefert in Eclipse Kompilierfehler

Prozesskommunikation mit PIPES - wie funktioniert das?

Server und Client für TCP und UDP

Ausführbare C-Datei von Mac OS auf Embedded Linux ausführen

Zurück
Oben