Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Dateiverarbeitung

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
17.11.2005, 10:00 Uhr
FeriX



Hallo,

ich schreibe gerade an einem Programm in C für die FH und habe da ab einem gewissen Punkt ein paar Probs. Ich paste gerade mal die Aufgabe und erkläre euch dann mal wo ich nicht weiterkomme.

In Unix-Dateien werden die Daten als Bytestream
gespeichert. Mit der Routine fseek() können Sie innerhalb
einer Datei positionieren, mit fread() lassen sich Daten
lesen und mit fwrite() können Daten geschrieben werden.
Legen Sie für die folgenden Daten je eine Unix-Datei an.
Person:

PID:> P_Name (20 Zeichen), P_Vorname (15 Zeichen), Geb.Datum, PLZ, Wohnort

KFZ:
KFZ-Nr:> F_Typ, F_Marke, F_Modell, Baujahr

Um möglichst schnell an einen Datensatz heran zu
kommen, ist es sinnvoll zusätzlich eine Index-Datei
anzulegen. D.h. wenn man z.B. nach einem Namen
suchen möchte, so muss es eine Index-Datei für Namen
geben, in der als Datenelemente die Namen und die
Adresse (Offset) von Datensätzen (mit diesem Namen)
gespeichert sind. Um den schnellen Zugriff auf
Fahrzeugtypen (F_Typ) zu ermöglichen, ist ebenfalls eine
Index-Datei erforderlich.

Schreiben Sie die notwendigen Routinen für:
– die Erfassung von Datensätzen
– die Speicherung von Datensätzen
– das Anlegen von Index-Dateien
– und die Suche von Datensätzen via Index-Dateien


So die Erfassung der Datensätze und das Speichern in der Datei ist nicht das Problem. Das habe ich mit der Erstellung eines char buffer[], in den ich die einzelnen Daten einlese und dann mit fwrite in die Datei schreibe realisiert.

Mein Problem ist eben, dass ich nichts mit diesen index-Dateien anfangen kann.
Für was sollen die genau sein? Bzw. was soll genau in diese reingeschrieben werden wenn man sie anlegt!?

Dementprechend weiß ich natürlich auch nicht wie ich das mit dem suchen machen soll.

Vielleicht kann mir da jemand ein paar Anstoßpunkte geben, die mich ein wenig weiterbringen!? Wäre super!

Greetz
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.11.2005, 10:14 Uhr
Sponge



Moin,
also so wie ich das verstehe und das macht meiner meinung nach den meisten Sinn, sollst du eine Indexdatei anlegen, also z.B. hast du einen Hans Meier. Seine Daten fangen in der Datendatei an der Position 29 an, also ab dem 29. Byte, damit hast du den Offset in der Datendatei zu einem ganz bestimmten Eintrag. Dadurch brauchst du bei grossen Datensätze nicht die gesamten Daten auslesen und immer vergleichen, ob du das was du suchst schon gefunden hast, sondern kannst gleich mit dem Offset zu der Position springen. Dafür musst du allerdings die Indexdatei durchsuchen nach dem Eintrag den du suchst, diese Datei ist allerdings kleiner, weil ja Geburtsdatum, Wohnort und so nicht vorhanden sind.
Dazu brauchst du dann die Funktion fseek, mit der Du dann deinen FilePointer an den Offset verschieben kannst.

Hoffe konnte dir etwas weiterhelfen.
--
Es gibt 10 Arten von Leuten:
die, die das binäre System verstanden haben,
und die, die es nicht verstanden haben ^^
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
17.11.2005, 10:21 Uhr
FeriX



aha jetzt verstehe ich das zumindest schonmal ein bisschen mehr...

aber was genau in die index-Datei geschrieben werden muss verstehe ich jetzt nicht so ganz...

nur die namen und der zugehörige offset aus der datendatei!?

um dann mit fseek auf die daten zu springen!?

...und das nächste prob ist ich habe mal wieder kein plan wie ich das realisieren könnte grrrr
wir haben nämlich in der vorlesung zum thema dateiverarbeitung etc. noch nichts an stoff durchgenommen und dementsprechend habe ich in dieser richtung bisher auch noch nichts programmiert.

Dieser Post wurde am 17.11.2005 um 10:23 Uhr von FeriX editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
17.11.2005, 10:37 Uhr
Sponge



ja so versteht ich das, man könnte es auch als INI Datei gestalten (glaub aber das gibts unter LINUX nicht)

Code:
[Meier, Hans]
29
[Schulz, Sabine]
58



bzw.


Code:
Meier, Hans : 29
Schulz, Sabine : 58



Im Falle der INI datei könntest du die Funktionen GetPrivatProfileSection z.B. benutzen, aber ich glaube die gibts nur unter Windows
Das Problem was ich dabei nur sehe, ist die Eindeutigkeit, weil es ja evtl 2x Sabine Schulz gibt...


So nun zur Implementierung.. habe zwar lange nix mehr mit Dateihandling gemacht, aber ich versuch mal mein Glück.
also wie gesagt mit fseek kannst du immer an die nächste Stelle springen

Code:
int fseek(FILE * stream, long offset, int origin)



also stream ist klar, ist dein Dateihandler, offset ist der Offset den du an deiner Indexdatei hast und origin ist die Anfangsposition, die ja 0 wäre (dann springst du immer vom Anfang der Datei) Der Returnwert der Funktion ist 0 wenn es erfolgreich war

So nun wie kommst du zu deinem Offset ?
ich denke es könnte mit fgetpos() funktionieren

Code:
int fgetpos(FILE *stream, fpos_t * pos)



stream ist wieder dein Dateihandler und pos ein Pointer auf eine Zahl in der dann dein Offset gespeichert wird. Der Returnwert der Funktion ist 0, wenn es erfolgreich war, sont ungleich 0, dann wird auch errno gesetzt

Na dann wünsch ich Dir viel spass
--
Es gibt 10 Arten von Leuten:
die, die das binäre System verstanden haben,
und die, die es nicht verstanden haben ^^
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
17.11.2005, 10:42 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Du musst dir beim Anlegen eines Datensatzes einfach merken wo er beginnt und dieses inklusive einem eindeutigen Schlüssel des Datensatzes schreibst du dann in deine Indexdatei... Wenn du dann wieder auf den Datensatz zugreifen willst weisst du schon wo er innerhalb der Datei liegt indem du einfach in der Indexdatei suchst, die ja viel kürzer ist als die andere Datei da du hier nicht den ganzen Datensatz speicherst sondern nur einen eindeutigen Schlüssel für den Datensatz. Findest du den Schlüssel in der Indexdatei springst du innerhalb der Datendatei an den dafür in der Indexdatei gemerketen offset und hast den gesuchten Datensatz...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
17.11.2005, 10:48 Uhr
0xdeadbeef
Gott
(Operator)


Wichtig ist die Verarbeitung des Index. Im Grunde ist die Indexdatei selbst nicht besonders kompliziert, ich würde vorschlagen, sie einfach space-padded so aufzubauen, dass sie dem Format "Offset Datum" entspricht, im Fall von Namen also

Code:
102 Hindenburg
0 Meier
50 Müller


Wichtig zu beachten dabei ist, bei der Suche wird das Datum, nicht das Offset als Schlüssel benutzt. Je nachdem, wie du den Index nachher verarbeiten willst, kann es also Sinn machen, die Indexdatei nach dem Datum zu sortieren (wie ich es oben getan habe). In dem Fall könnte man sie zum Beispiel einfach in ein Array einlesen und dann binär suchen. Wenn du mit einem Baum arbeiten willst, ist das Sortieren eher ungünstig, weil du dann die ganze Zeit am Ausbalancieren bist. Die Deluxe-Lösung ist natürlich eine Hashtable, der ist das je nach Hashfunktion herzlich egal, ob die Datei sortiert ist oder nicht.

Ich nehme aber an, dass in der Aufgabenstellung das Einlesen in ein Array gemeint ist, da sich sowohl Baum als auch Hashtable locker auch ohne spezielle Indexdatei direkt aus den Datensätzen generieren ließen.

Als weitere Verfeinerung würde ich darüber nachdenken, am Anfang der Datei die Anzahl der enthaltenen Datensätze zu speichern und evtl. die Länge des Datums, um nicht zu viel Speicher anfordern zu müssen. Das sähe dann so aus:

Code:
3
102 10 Hindenburg
0 5 Meier
50 6 Müller


und ließe sich in folgender Form verarbeiten:

C++:
#include <stdio.h>
#include <stdlib.h>

struct name_index_data {
  char *name;
  long offset;
};

int main(int argc, char *argv[]) {
  struct name_index_data *name_index;
  int name_index_len, data_len, i;
  long offset;
  FILE *fd = fopen("name.idx", "r");

  fscanf(fd, "%d", &name_index_len);
  name_index = calloc(name_index_len, sizeof(struct name_index_data));

  for(i = 0; i < name_index_len; ++i) {
    fscanf(fd, "%ld %d ", &offset, &data_len);
    name_index[i].offset = offset;
    name_index[i].name = malloc(data_len + 1);
    fread(name_index[i].name, sizeof(char), data_len, fd);
  }

  for(i = 0; i < name_index_len; ++i) {
    printf("%s %ld\n", name_index[i].name, name_index[i].offset);
    free(name_index[i].name);
  }

  free(name_index);

  return 0;
}


Natürlich würdest du name_index irgendwo in geeigneter Form aufbewahren und nicht gleich wieder freigeben, und ein paar Zugriffsfunktionen empfehlen sich auch, aber das grobe Prinzip sollte klar werden.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: