Binär einlesen/auslesen(fread, fwrite)

Das ist, weil sich scanf und gets nicht vertragen.

Nimm die Funktion dazu:
C++:
int File::readint()
{
	int i;
	char buffer[20];
	if(NULL == fgets(buffer, 20, stdin))
		return -1;
	i = strlen(buffer) - 1;
	if(i >= 0 && buffer[i] == '\n')
		buffer[i] = '\0';
	else
	{
		while(fgetc(stdin) != '\n');
	}
	if(1 != sscanf(buffer, "%d", &i))
		return -1;
	return i;
}
und schreib statt dem scanf für anz im main das:
C++:
anz = readint();

Gruß
 
Danke!

Ich hab jetzt alle Aufgaben erfüllt bis auf das Löschen eines Termins.

Folgendes hab ich mir gedacht:
Ich lese aus dem binär file aus, gebe das Thema des Termins ein der gelöscht werden soll, such den dann, wenn ich die position gefunden habe vom Termin dann überschreibe ich diesen Termin mit dem nächsten usw.

Also ich hab 5 Termine und der 3. soll gelöscht werden...

12345 --> der 4. termin wird auf position 3 geschrieben und der 5. Termin auf Position 4 -> 1245

Was ist dann mit der 5. Position da bleibt doch eine Kopie vom 5. Termin erhalten oder?

Ein Problem tritt auch auf, wenn ich den 5. Termin löschen will wie mache ich das? Da kann ich ja nichts überscheiben oder?

Hier mein Versuch:
C++:
void termin_löschen(char filename[])
{
	FILE* outFile=NULL;
  FILE* inFile=NULL;

  termine* termindata=NULL;
	termine* hilf=NULL;
  termine thema;

	int anz=0;

  anz=file_len(filename);//hier wird die Anzahl der Termine die im File stehn ermittelt --> anz=Anzahl der Termine

	termindata=(termine *)malloc(sizeof(termine)*anz);
	if(termindata != NULL)
	{
		hilf=termindata;
	  outFile=fopen(filename,"rb");
		if(outFile == NULL)
		{
			printf("The files %s could not be opened",filename);
			exit(-1);
		}
	  
		fread(termindata,sizeof(termine),anz,outFile);

		fclose(outFile);

		inFile=fopen(filename,"wb");
		if(inFile == NULL)
		{
		  printf("The file %s could not be opened!");
			exit(-1);
		}

		printf("Geben Sie das Thema des Termins ein, der geloescht werden soll:")
		scanf("%s",thema.thema);

		for(x=0; x<anz; x++)
		{
		  if(thema.thema == termindata->thema)
			{
				//hier werden halt die ganzen Termine verschoben bzw. eine Schleife ist auch noch notwendig, aber ich kanns einfach nicht umsetzen...
			}
			termindata++;
		}

		free(hilf);
	}
	else
	{
	  printf("Memory allocation failure!");
	}
}
 
Hi.

Du solltest einfach die Termine aus der Datei in den Speicher laden.

Manipuliere die Termine im Speicher und schreibe die Termine komplett neu in die Datei (alte Datei überschreiben).

\edit: Eine Liste würde sich für die Verwaltung der Termine im Speicher vermutlich am besten eignen. Zumal es eine ziemlich simple Datenstruktur ist.

Gruß
 
Hi

zuerst was Anderes: Bei deiner Löschfunktion musst du nach
Einlesen und Löschen die Datei auch wieder beschreiben.
Sonst ists ja sinnlos, wenn der zu löschende Termin in der Datei noch existiert.

Zum Löschen selber: Du denkst richtig.
Aus einem Array "gelöscht" wird, in dem man alles
nach dem betroffenen Element eins nach vorne verschiebt/kopiert.

Dass es vom Letzten dann zwei gibt ist auch richtig, aber:
Ignorier das Gesamt-Letzte einfach.
Du liest 5 Elemente ein, 12345
Du löscht 3, ergib 12455.
Du weißt aber, dass es jetzt nur noch 4 Elemente sind,
und schreibst nur 4 wieder in die Datei.
1245.

Zum Löschen des Letzten:
Geht eigentlich genau so, es gibt dahinter nur nichts,
das verschoben/kopiert werden kann.
Da man das Verschieben in einer Schleife macht, von x bis Ende,
und Ende dann eben sofort ist, braucht es keine Sonderbehandlung.
 
Danke, ich habs nun aber ein bisschen anders probiert, weil ich das mit dem schieben nicht wirklich hinbekommen habe.

Ich geb ein Thema ein z.B. "lernen", die if-anweisung wird voll ignoriert warum?
C++:
void termin_löschen(char filename[])
{
	FILE* outFile=NULL;
  FILE* inFile=NULL;

  termine* termindata = NULL;
	termine* hilf = NULL;
  char thema[100];

	int x=0;
	int anz=0;

	anz=file_len(filename);

	fflush(stdin);
	printf("Geben Sie das Thema des Termins ein, der geloescht werden soll:");
	gets(thema);

	termindata=(termine *)malloc(sizeof(termine)* anz);
  if(termindata != NULL)
	{
		hilf=termindata;
		outFile=fopen(filename,"rb");
		if(outFile == NULL)
		{
			printf("The file %s could not be opened",filename);
		}

		fread(termindata,sizeof(termine),anz,outFile);

		fclose(outFile);

		inFile=fopen(filename,"wb");
		if(inFile == NULL)
		{
			printf("The file %s could not be opened",filename);
		}

		for(x=0; x<anz; x++)
		{
		  if(thema != termindata->thema)
			{
			  fwrite(termindata,sizeof(termine),1,inFile);
			}
			termindata++;
		}

		fclose(inFile);
	}
	else
	{
	  printf("Memory allocation failure!");
	}

	free(hilf);
}
 
Zuletzt bearbeitet:
So, mit dem Sofort-Schreiben, gehts natürlich auch.
Der Fehler: char-Array-Strings werden mit strcmp verglichen.

Du vergleichst da, ob es die selben Strings sind
(nicht nur der gleiche Inhalt, sondern wirklich ein- und derselbe String).
Zum Inhaltsvergleich:
C++:
if(strcmp(thema, termindata->thema))
 
Die Aufgabe ist das man einen bestimmten Termin suchen muss im Binärfile und dann auslesen.
Meine Idee: Ich geben vorher das Datum ein und dann vergleiche ich das Datum mit den Datums im Binärfile wenn die gleich sind speichere ich sie in eine Adresse wo ein Pointer draufzeigt, da es ja mehrere Termine an einem Tag geben kann. Problem ist nur das ich 2mal fast den selben Vorgang mache und das ist nicht gut.

Hier mal der Ausschnitt:

C++:
termin* termin_search(char filename[])
{
  FILE* outFile=NULL;
	termin temp;
	timestamp dat_von;
	termin* term_gesucht=NULL;
	int anz=0;


	outFile=fopen(filename,"r+b");
	if(outFile == NULL)
	{
	  printf("File %s could not be opened!",filename);
		exit(-1);
	}
  
	printf("Geben Sie das Datum des/der gesuchten Termin(e) ein(TTMMJJ):");
	scanf("%d",dat_von.tag);
	scanf("%d",dat_von.mon);
	scanf("%d",dat_von.jahr);

  while(!feof(outFile))
	{
	  fread(&temp,sizeof(termin),1,outFile);

		if(temp.von.tag == dat_von.tag && temp.von.mon == dat_von.mon && temp.von.jahr == dat_von.jahr)
		{
		  anz++;
		}
	}

	rewind(outFile);

  term_gesucht=malloc(sizeof(termin)*anz);

	while(!feof(outFile))
	{
	  fread(&temp,sizeof(termin),1,outFile);

		if(temp.von.tag == dat_von.tag && temp.von.mon == dat_von.mon && temp.von.jahr == dat_von.jahr)
		{
		  //hier käme dann das lange zuweisen, aber das dauert ja ewig zum schreiben^^
		}
	}

	return(term_gesucht);
}


Hier die lange Struktur:

C++:
struct timestamp_struct
{
short jahr;
short mon;
short tag;
int min;
};
typedef struct timestamp_struct timestamp;

struct termin_struct
{
char thema[MAX_THEMALEN];
timestamp von;
timestamp bis;
char teilnehmer[MAX_TEILNEHMER];
short priority;
char beschreibung[MAX_BESCHR];
short status;
};
typedef struct termin_struct termin;

Natürlich könnte ich die gesuchten Termine auch gleich im Unterprogramm ausgeben, aber zum Ausgeben habe ich eine weitere Funktion, die ich dann im Hauptprogramm aufrufen werde.

Diese sieht so aus:
C++:
void termin_out(termin termin_zur_ausgabe)
{
printf("------------------\n");
printf("Termin: %s \nTeilnehmer %s \nprio %d \nBeschreibung: %s \nStatus %d\n",termin_zur_ausgabe.thema,termin_zur_ausgabe.teilnehmer,termin_zur_ausgabe.priority,termin_zur_ausgabe.beschreibung,termin_zur_ausgabe.status);
printf("------------------\n");
}
 
Du kannst die Ausgebe-Funktion doch auch aus dem "Unterprogramm" aufrufen.
main ist nicht die einzige Stelle, wo man FUnktionen aufufen kann.
Das kann ziemlich verschachtelt werden.
 
Ok, danke aber ich kann trotzdem nicht die 2 gleichen schleifen umgehn. Wenn ich mit Pointer mach muss ich ja die anz wissen für malloc und wenn i mit Array mache dann muss ich auch irgendwie Größe wissen, da ich kann ja net einfach 100 elemente definieren oder so. Ja klar kann ich das aber ist doof irgendwie. Ist wie beim malloc einfach schreiben sizeof(termin)*100 oder?
 
Die Gesamtanzahl der Termine muss vorher bekannt sein.
Wenn du 100 nehmen würdest, wäre es ja trotzdem möglich,
101 Ergebnisse reinspeichern zu müssen...
Also, wenn nicht im Programm vorher schon gemacht, abzählen.

Bitte Netiquette 15 beachten.
 
Zurück