Problem mit Struct schreiben und einlesen



  • Hallo,

    ich beschäftige mich zur Zeit mit einem Programm zur Routenberechnung und habe mir ein kleines Tool geschrieben um mit Punkte und Wege für meine Berechnung in einer Datei einzufügen.
    Im Prinzip funktioniert es auch, aber nicht immer 😞
    Es gibt einige wenige Punkte, die nicht ordentlich eingetragen werden und meine Datei "versauen".
    Aber erst einmal die wichtigsten Code-Teile:
    DatenImport.h:

    struct WEG{
    		char		name[50];
    		int		nach;
    		double		distanz;
    		int		art;
    		double		faktor;
    
    	};
    	struct PUNKT{
    		char		name[30];
    		int		lat;
    		int		lon;
    		char		anzeigen;
    		int		art;
    		struct WEG	weg[10];
    	};
    
    char F_hauptmenu();
    void F_menue_hin();
    void F_menue_zeigen();
    int punkt_laden(int eintrag, struct PUNKT* punkt);
    void punkte_einfuegen();
    void weg_einfuegen();
    int F_Punkt_schreiben(struct PUNKT punkt);
    int punkte_anzeigen()
    

    und aus der funk.c:

    void punkte_einfuegen()
    {
    	int lat_grad , lon_grad;
    	double lat_min,lat_sek, lon_min,lon_sek,lat,lon;
    	struct PUNKT neu;
    	system("CLS");
    	printf("Punkte einfuegen");
    	printf("\n################################################################################");
    	printf("\n\nBitte machen Sie folgende Angaben:");
    	printf("\nName: ");
    	scanf("%s",&neu.name);
    	printf("Lat: ");
    	scanf("%d",&lat_grad);
    	scanf("%lf",&lat_min);
    	scanf("%lf",&lat_sek);
    	printf("Lon: ");
    	scanf("%d",&lon_grad);
    	scanf("%lf",&lon_min);
    	scanf("%lf",&lon_sek);
    	scanf("%c",&l);
    	printf("Anzeigen?: ");
    	scanf("%c",&neu.anzeigen);
    	printf("Art: ");
    	scanf("%d",&neu.art);
    	lat=((lat_sek/6000)+(lat_min/60)+lat_grad)*1000000;
    	lon=((lon_sek/6000)+(lon_min/60)+lon_grad)*1000000;
    	neu.lat=int(lat);
    	neu.lon=int(lon);
    	if(F_Punkt_schreiben(neu)==1)
    	{
    		printf("\n\n\nweiter mit belieger Taste..");
    		_getch();
    	}
    
    }
    [...]
    int F_Punkt_schreiben(struct PUNKT punkt)
    {
    	FILE* fp;
    	fpos_t  pos;
    	if((fp=fopen("../punkte.dat","a+"))!=NULL)
    	{
    		int fwr, fehler;
    		if(fwr=fwrite(&punkt,sizeof(struct PUNKT),1,fp))
    		{
    
    			fseek(fp, 0, SEEK_END);
    			fgetpos(fp,&pos);
    
    			fehler=ferror( fp );
    			printf("\nFEHLER: %d",fehler);
    			printf("\nAnzeigen: %d - Art = %d\nLat: %d\nLon: %d\nName: %s",punkt.anzeigen,punkt.art,punkt.lat,punkt.lon,punkt.name);
    			fclose(fp);
    			printf("\nfwrite: %d\nEintraggrosse: %d \nDateigroesse %d,Eintrag %d",fwr,sizeof(struct PUNKT),pos,int((int(pos)/sizeof(struct PUNKT))));
    			return 1;
    		}
    		else
    		{
    			fclose(fp);
    			return 0;
    		}	
    	}
    	else
    	{
    		return 0;
    	}
    
    	fclose(fp);
    }
    

    Wie man sieht lass ich mir schon alles mögliche zur Kontrolle noch einmal anzeigen, aber laut diesen Meldungen gibt es keinen Fehler.

    Jedoch werden einige diese einige wenige Einträge nicht mehr beim Einladen angezeigt.

    int punkte_anzeigen()
    {
    	int i=0;
    	struct PUNKT punkt;
    	system("CLS");
    	printf("Punkte anzeigen");
    	printf("\n################################################################################");
    	printf("\n\nfolgenden Eintraege stehen zur Verfuegung:");
    	while(punkt_laden(i, &punkt))
    	{
    		printf("\n%2d - %s, %d, %d",i+1, punkt.name, punkt.lat, punkt.lon);
    		i++;
    	}
    	printf("\n\nWelcher Eintrag soll gezeigt werden? ");
    	scanf("\n%d", &i);
    	return (i-1);
    }
    [...]
    int punkt_laden(int eintrag, struct PUNKT* punkt)
    {
    	FILE* fp;
    	if((fp=fopen("../punkte.dat","r"))!=NULL)
    	{
    		fseek(fp, eintrag*sizeof(struct PUNKT), SEEK_SET);
    		int f,fehler;
    		if(f=fread(punkt,sizeof(struct PUNKT),1,fp))
    		{
    			fehler=ferror( fp );
    			printf("\nFEHLER: %d",fehler);
    			fclose(fp);
    			return f;
    		}
    		else
    		{
    
    			fehler=ferror( fp );
    			printf("\nFEHLER: %d",fehler);
    			fclose(fp);
    
    			return 0;
    		}
    	}
    	else
    	{
    		printf("FEHLER: Datei wurde nicht geoeffnet");
    		return 0;
    	}
    }
    

    das ganze geht zum Beispiel bei der Eingabe folgenden Daten

    0	Hamburg			 53°33'12.27"N	 9°59'31.91"O
    1	Horster Dreieck	 53°22'48.84"N	10° 1' 1.41"E
    2	Maschener Kreuz	 53°23'27.57"N	10° 1'21.76"E
    3	Dreieck Schwerin	53°25'15.39"N	11°31'18.57"E
    4	Schwerin			53°37'32.71"N	11°25' 0.75"O
    5	Bremen			  53° 4'29.93"N	 8°48'25.49"O
    6	Dreieck Walsrode	52°47'14.49"N	 9°40'14.06"E
    7	Hannover			52°22'19.44"N	 9°44' 8.47"O
    8	Lüneburg			53°14'45.38"N	10°24'33.63"O
    9	Rostock			 54° 5'24.48"N	12° 7'58.64"O
    10	Lübeck			 53°52'10.43"N	10°41'15.28"O
    11	Berlin			 52°31'24.53"N	13°24'41.38"O
    12	Magdeburg		  52° 7'51.44"N	11°38'12.12"O
    13	Braunschweig	   52°15'50.91"N	10°31'34.97"O
    14	Osnabrück		  52°16' 2.18"N	 8° 3'11.49"O
    15	Münster			51°57'52.96"N	 7°37'42.59"O
    16	Cottbus			51°45'38.82"N	14°19'38.93"O
    

    Jedoch zBsp folgenden Orten treten die Probleme auf:

    Dresden			   51° 3' 3.45"N	13°44' 1.17"O
    Dreieck Nossen		51° 3'13.14"N	13°21'59.80"E
    Dreieck Salzgitter	52° 5' 8.00"N	10°10'57.50"E
    

    Ich wäre Dankbar für jeden Tipp, denn ich selber hab mit C/C++ noch fast gar keine Erfahrung.
    Also schon einmal vielen Dank im voraus.



  • Wo ist jetzt der Unterschied bei deinen beiden Beispielausgaben?



  • Das Problem ist, das bei den letzten drei Koordinaten es aus mir unbekanten Gründen zu Fehlern kommt. Die Werte werden falsch berechnet, falsch in die Datei geschrieben, was beim Auslesen wiederum zu Fehlern führt.



  • Mein Chef war gerade vorbei gekommen und sich das ganze einmal angeschaut was ich so fabriziert habe und nach intensiver Suche hat er den Fehler auch gefunden.
    Es haben nur zwei kleine b gefehlt 😉

    statt:
    if((fp=fopen("../punkte.dat","a+"))!=NULL)
    muss es:
    if((fp=fopen("../punkte.dat","ab+"))!=NULL)
    
    und statt
    if((fp=fopen("../punkte.dat","r"))!=NULL)
    muss es:
    if((fp=fopen("../punkte.dat","rb"))!=NULL)
    
    lauten
    


  • Dann ist dein Problem gelöst?
    Dennoch weitere Hinweise ....

    punkte_einfuegen():

    1. "l" wird referenziert ... ist aber nicht deklariert
    2. "int(lat)"? Willst du hier casten? Dann: "(int)lat"
    3. "F_Punkt_schreiben(neu)" ... hier sollte besser die adresse des structs übergeben werden

    F_Punkt_schreiben(neu):

    1. fclose(fp) am ende wird niemals erreicht.
    2. anzeigen wird hier als integer ausgegeben (%d) ist im struct aber ein char
    3. wie gesagt sollte das struct als pointer übergeben werden ... wie bei deiner lade funktion

    (...) und weiter bin ich noch nicht dem Progammablauf gefolgt. Wenn es funktioniert ist es also ok. Aber der Aufbau des Quellcodes ist überarbeitungswürdig.



  • Ja, das Problem ist damit gelöst und auch ein anderes dem ich mich jetzt noch gar nicht gewidmet hatte.

    Danke für die Hinweise, um diese werd ich morgen gleich kümmern. Aber zur Zeit programmier ich einfach drauf los, ohne vorher drüber nach zu denken. Da ich jetzt erst angefangen hab mich mit C bzw C++ zu beschäftigen 😉


Anmelden zum Antworten