Virtuelles File System in C schreiben



  • @DonChunior:
    Danke 🙂 👍



  • am Anfang wird ein Pfad mitgegeben und ich brauche diesen Pfad zweimal, einmal um die store-Datei zu erstellen und einmal um die structure-Datei zu erstellen...

    ich hatte zuerst den pfad am Anfang in zwei charArrays gepackt:
    char *pfadStore = pfad;
    char *pfadStructure = pfad;

    Das funktioniert aber nicht vermutlich weil pfad nur ein Zeiger ist und die beiden anderen auch Zeiger, sodass alle 3 auf den gleichen Speicherplatz zeigen.
    Wie bekomme ich das nun hin?
    Ich hab auch schon versucht zuerst einfach den pfadStore zu benutzen und dann an die länge-6 ".structure" zu schreiben >> funktioniert auch nicht



  • ...



  • Hallo, ich bin nun auf ein anderes Problem gestoßen.
    Wie kann ich die Eingabedatei einlesen und dann an eine bestimmte Stelle in meiner .store-Datei schreiben?

    Das mit der Stelle klappt glaube ich schon mit fseek(). Aber der Inhalt kommt nicht richtig rüber. Ich habe dann erstmal versucht die eingelesenen Inhalte auf der Konsole auszugeben.
    fgetc(): da wird immer nur SOH ausgegeben
    fread(puffer, 5, 2, eingabe):
    Erster Aufruf: Es landen die ersten 10 Zeichen im puffer aber danach kommen noch andere Zeichen und dann nochmal der komplette Inhalt, also ungefähr so:
    "Das ist di|<|||||||<|||>Das ist die Eingabedatei"
    Zweiter Aufruf: Es landen die nächsten 10 Zeichen im Puffer und wieder noch andere Zeichen: "e Eingabed|<|||||||<|||>Das ist die Eingabedatei"
    Dabei ist der puffer bei mir nur 10 Zeichen groß.

    fgets(): Der Inhalt wird richtig auf der Konsole ausgegeben aber das kann ich leider nicht benutzen weil ich nicht weiß wie lang eine Zeile ist und die Vorgabe ist, dass wir beliebig große Dateien einlesen müssen.



  • 1. Das mit dem Einlesen funktioniert jetzt mit fgetc()

    ist das zu langsam um beliebig große Dateien zu speichern?

    Ich benutze auch vorher so eine Schleife:
    [code="c"] anzahl = 0;

    while(fgetc(eingabe) != EOF) {
    anzahl++;
    }
    [/code="c"]

    um herauszufinden wie große die Datei ist, ob sie noch in mein system passt. Ich könnte mir vorstellen, dass es bei großen Dateien schwierig werden könnte.



  • Ich würde mich auch über einen Tipp zur Positionierung des Zeigers in der .store-Datei freuen.
    Egal welche Operation ich darauf ausführe: fseek(), rewind() der Inhalt wird immer ans Ende der Datei geschrieben. Wenn ich mir allerdings die aktuelle Position ausgeben lasse mit ftell() dann wird immer 0 ausgegeben. 😕 😕 😕



  • C_Mond schrieb:

    der Inhalt wird immer ans Ende der Datei geschrieben.

    Klingt danach, dass du "a" als Argument bei fopen verwendet hast.
    Wenn du keine absolute Positionierung an festen Dateipositionen benötigst, schaue dir fgetpos/fsetpos an, wenn du innerhalb derselben Datei wechselseitig schreibst/liest, musst du dazwischen explizit flushen.



  • nein ich lese und schreibe nicht aus der gleichen Datei
    ich lese aus der eingabedatei und schreibe in die .store-Datei
    aber dort möchte ich eben den zeiger beliebig positionieren können

    ja, ich benutze "a" als Argument aber da wird es eben immer ans Ende geschrieben auch wenn ich den zeiger umpositioniere, mit "a+" ist es dasselbe
    wenn ich aber "w" benutze dann wird der inhalt zwar an die richtige Stelle geschrieben aber die stellen davor werden mit "Nul" aufgefüllt und dahinter der Inhalt ist nicht mehr da...die Datei wird also neu erstellt

    was ist möchte ich folgendes:
    vorher: 00000000000000000000000000000000000000irgendein anderer inhalt0000
    nachher:00000Das ist die Eingabedatei000000000irgendein anderer inhalt0000

    fsetpos() funktioniert deswegen nicht weil man dafür die systemvariable fpos_t bruacht und die kann ich nicht von hand belegen ich könnte höchstens eine stelle an der der zeiger ist abfangen und später weiterbenutzen aber das ist nicht das, was ich brauche



  • "r+" habe ich übrigens auch schon probiert: gleicher Effekt wie bei "a" und "a+".
    Alle Inhalte werden ans Ende der Datei geschrieben, egal wie der Zeiger positioniert ist 😡



  • Eine andere Möglichkeit wäre vielleicht bis zum Einstiegspunkt zu lesen, dann anzufangen zu schreiben.
    Das geht leider nicht weil in der .store-Datei wirklich nur der reine Inhalt stehen darf. D.h. ich habe keine Möglichkeit in der Datei selbst herauszufinden, ob ein bestimmter Inhalt zu Ende ist oder nicht.

    Langsam gehn mir die Ideen aus.



  • Eine Idee habe ich noch: ich könnte immer vom Anfang der Datei bis zu der Stelle lesen wo ich schreiben möchte und dann anfangen zu schreiben. Allerdings funktioniert das aktuell noch nicht.

    Hier der Code dazu:
    [code="c"]
    int eof;

    store = fopen(pfad, "r+");
    eingabe = fopen(source, "r");
    for(zaehler=0;zaehler<=5;zaehler++) {
    fgetc(store);
    }
    // Hier ist die Position auf 6
    eof = fgetc(eingabe);
    fputc(eof, store);
    fflush(store);

    fclose(store);
    fclose(eingabe);

    [/code="c"]



  • C_Mond schrieb:

    "r+" habe ich übrigens auch schon probiert: gleicher Effekt wie bei "a" und "a+".
    Alle Inhalte werden ans Ende der Datei geschrieben, egal wie der Zeiger positioniert ist 😡

    Quatsch.
    Dein Fehler. Der Compiler/die Standardbibliothek macht keine Fehler.
    Explizit positionieren kannst du nicht über das aktuelle Dateiende hinaus.
    r+ schreibt ab der aktuellen Position.
    Mit diesen beiden Erkenntnissen sollte es wohl nicht mehr allzu schwierig sein.



  • Habe es inzwischen hinbekommen, Danke.

    Jetzt habe ich eine andere Frage: man soll in die Structure-Datei ungefähr so etwas schreiben:
    Dateiname1,1000,1,0 wobei die 1000 laut Aufgabenstellung die tatächliche Länge der Datei darstellt und nicht den belegten Platz im VFS.
    Nur wo ist da der Unterschied? Und wenn es einen Unterschied gibt wie ermittelt man die tatsächliche Länge?



  • hallo,
    ich komme bei einem Problem nicht weiter.
    ich habe in einer Datei folgendes stehen: 11110001010
    und lese nun die einzelnen Zeichen nacheinander so ein
    [code="c"]
    int zeichen;
    fscanf(datei, "%c", &zeichen);
    printf("Zeichen ist: %c\n", zeichen);
    [/code="c"]

    Das funktioniert auch soweit. Dann möchte ich aber folgendes tun:
    [code="c"]
    if(zeichen==0) {
    //tue irgendwas;
    }
    [/code="c"]

    aber es funktioniert nicht, die if-Bedingung ist immer false, auch wenn ich so prüfe
    [code="c"]
    if(zeichen=='0') {
    //tue irgendwas;
    }
    [/code="c"]

    Hat jemand eine Idee, wie das richtig funktioniert?


  • Mod

    So wie Nummer 2 ist es richtig(er) (das Einlesen an sich sieht schon ungünstig aus). Bitte vollständige Minimalbeispiele bei solcher Art von Problemen. Siehe dritter Link in meiner Signatur.



  • okay, in Zukunft vollständige Beispiele 🙂

    ich hab das Einlesen auf fgetc geändert und jetzt funktionierts wenn ich
    auf '0' vergleiche 👍



  • Hallo, vielleicht kann mir einer von euch bei folgender Sache helfen?

    Ich habe eine Datei, die ungefähr so aussieht:
    10
    5
    2
    11000
    name, 24, 0, 1

    und möchte darin lesen bis ich zu dem String "name" komme
    also ungefähr so:
    [code="c"]
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <io.h>
    #include <ctype.h>

    add(char *pfadDatei) {
    int gefunden, buchstabe;
    FILE *datei;
    char *dateiname;
    fpos_t pos;

    datei = fopen(pfadDatei, "r");
    gefunden = 0;
    while(gefunden==0) {
    buchstabe = fgetc(datei);
    if(isalpha(buchstabe)) {
    gefunden = 1;
    }
    }
    fgetpos(datei, &pos);
    pos = pos-1;
    fsetpos(datei, &pos);
    fscanf(datei, "%s", &dateiname);

    //tue irgendwas mit dem dateinamen
    fclose(datei);
    return 0;
    }

    int main(int argc, char *argv[]) {
    add(argv[1]);
    }

    [/code="c"]

    Leider bekomme ich dann immer einen Nullpointer. Habe auch schon versucht mit
    ungetc() nichts funktioniert 😕



  • Du könntest die Zeile "name, 24, 0, 1" in eine Zeichenkette einlesen und mit strtok() deinen Inhalt herausschneiden. So zum Beispiel:

    char *a = strtok(zeichenkette,",");
    int b = atoi(strtok(NULL,","));
    int c = atoi(strtok(NULL,","));
    

    In a steht dann name, in b 24, in c 0 usw. Beim ersten Aufruf von strtok() gibt man die Zeichenkette mit und anschließend NULL, da die Methode einen internen Zeiger hat mit dem dann weiter gearbeitet wird. Das Komma wäre hier dann das Trennzeichen und wird nicht mitgelesen. Man kann es wahrscheinlich eleganter lösen aber so sollte es eigentlich klappen, du musst halt nur wissen an welcher Stelle in der Zeichenkette du welche Information stehen hast 😉



  • int add(const char *pfadDatei) {
    int gefunden=0;
    FILE *datei = fopen(pfadDatei, "r");
    char s[1000];
    while( fgets(s,1000,datei) )
    {
      if( strchr(s,',') )
      {
        char name[1000];
        *strchr(s,',')=0;
        strcpy(name,s);
        gefunden = 1;
    
        {
          ... hier irgendwas mit name[] machen
        }
    
        break;
      }
    }
    fclose(datei);
    return gefunden;
    }
    


  • Hallo, danke erstmal für eure Tipps 🙂 👍

    ich brauche nun wieder mal eure Hilfe und zwar für das Löschen:

    meine Structure-Datei sieht ungefähr so aus:
    datei1, 32,4,0,1,2,3
    datei2, 8,1,4
    datei3, 15,2,5,6

    wobei die erste Zahl für die tatsächliche Größe der Datei steht, die zweite Zahl für die Anzal der belegten Blöcke und danach werden dann einfach die Blöcke aufgezählt, in denen die Datei steht.
    Was ist nun wenn ich die Datei löschen möchte? Also, es geht mir dabei um die Anpassung der structure-Datei. Wenn zum Beispiel die Datei "datei2" gelöscht werden soll? Wie bekomme ich die Zeile aus der Datei heraus?
    Ich hatte die Idee die zu löschende Zeile einfach immer mit der letzten Zeile zu überschreiben aber das funktioniert nicht weil die Zeilen ja unterschiedlich lang sein können.
    Also wie bekomme ich die 2. Zeile tatsächlich gelöscht?? 😕


Anmelden zum Antworten