Virtuelles File System in C schreiben
-
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,6wobei 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??
-
Was haltet ihr von der Idee einfach an die erste Stelle der zu löschenden Zeile eine 10 zu schreiben für Zeilenumbruch?
Würde er dann beim Lesen einfach in die nächste Zeile springen automatisch auch wenn dahinter eigentlich noch andere Sachen stehn?
-
Meine Idee funktioniert nicht. Vorschläge sind immer noch erwünscht.
-
Speicher es eben gar nicht erst so, sondern in einem Format, das mit Änderungen zurecht kommt. tar und FAT wurden beide in diesem Thread schon oftmals genannt. Hast du eines davon mal angesehen? Solltest du, denn du versuchst schließlich, diese nachzumachen. Wie machen die das mit Änderungen? Ganz einfach: Feste Breite der Informationsfelder.
-
@Sepp:
diese Formate kenne ich tatsächlich nicht aber ich kann mir auch nicht irgendetwas beliebiges herauspicken. Wir haben die Vorgabe, dass es sich um eine .store-Datei speichern soll. Der Inhalt ist beliebig. Ich kann mir nicht vorstellen wie man da eins der beiden genannten Formate benutzen könnte.Das mit der festen Zeilenlänge finde ich allerdings einen guten Vorschlag
-
C_Mond schrieb:
@Sepp:
diese Formate kenne ich tatsächlich nicht aber ich kann mir auch nicht irgendetwas beliebiges herauspicken. Wir haben die Vorgabe, dass es sich um eine .store-Datei speichern soll. Der Inhalt ist beliebig. Ich kann mir nicht vorstellen wie man da eins der beiden genannten Formate benutzen könnte.Was hat irgendeine Dateiendung mit dem Format zu tun? Dateiendungen sind Schall und Rauch.
Du brauchst das Format ja auch nicht komplett zu übernehmen (im Falle von tar wäre dies jedoch eine gute Idee), aber sieh dir doch wenigstens mal an, wie das richtig gemacht wird.
-
@Sepp
Im Moment habe ich eine Lösung aber danke erstmal für deinen Tipp.Jetzt habe ich ein anderes Problem.
Ich versuche folgenden Code auszuführen:
[code="c"]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <ctype.h>int main(int argc, char *argv[]) {
FILE *eingabe;
int buchstabe;
int zaehler;
eingabe = fopen("C://test//Foto.JPG", "r");
if(eingabe == NULL) {
printf("Datei wurde nicht gefunden\n");
return 1;
}
zaehler=0;
buchstabe = fgetc(eingabe);
while(buchstabe != EOF) {
printf("Eingelesenes Zeichen als char:%c_und als int:_%d, Zaehler ist: %d\n", buchstabe, buchstabe, zaehler);
buchstabe = fgetc(eingabe);
zaehler++;
}
fclose(eingabe);
scanf("Pause");
return 0;
}
[code="c"]die Dateien, die ich durchlesen möchte sind jeweils beliebige Bilder, mehrere 100.000 Byte gross.
Das Problem ist, dass er keins bis zum Ende durchliest. Ich habe es mit verschiedenen Dateien probiert. Es scheint, als er an irgendeiner beliebigen Stelle entscheidet, dass dort eof ist.
Kann es sein, dass das auch zwischendurch in einer Datei ist und nicht nur am Ende???
-
Ist das nach 6 Seiten immer noch so schwer, die Codetags richtig zu benutzen? Es gibt doch sogar eine Vorschau, ob man es richtig gemacht hat.
-
An SeppJ
Wie wäre es, wenn du es ihm einfach mal erklärst anstatt zu meckern? Ich finde das in diesem Forum auch nicht gerade intuitiv.
-
Erster Thread im Forum:
http://www.c-plusplus.net/forum/310201
Anleitung zum Forum (oben rechts verlinkt):
http://www.c-plusplus.net/forum/faqIst das so schwer, so etwas selbstständig rauszufinden? Niemand sonst hat damit länger als 1-2 Beiträge lang Probleme.
Irgendwann muss man eben aufhören, eigentlich unlesbare Beiträge trotzdem zu lesen oder unzureichend beschriebene Probleme (*wink*wink*) mit der Kristallkugel zu lösen. Ohne negatives Feedback lernen manche Leute es sonst nie.
-
Hallo, ich muss mein Programm nun nur noch lauffähig auf linux bekommen.
Im Moment klappt es noch nicht weil ich oft folgendes mache:dateiStore = fopen(pfadStore, "rb"); dateiStructure = fopen(pfadStructure, "rb"); if(dateiStore != NULL || dateiStructure != NULL) { if(dateiStore != NULL) { printf("store ist nicht null\n"); fclose(dateiStore); } if(dateiStructure != NULL) { printf("structure ist nicht null\n"); fclose(dateiStructure); } printf("Mindestens eine der Dateien des vfs existiert bereits"); return 3; }
Falls kein gültiger Pfad angegeben wird, also einen, der nichtmal theoretisch existieren könnte, dann passiert genau in der ersten Zeile ein Speicherabzugsfehler.
Müsste da nicht einfach der Zeiger auch null sein?
-
Hallo Leute,
damit ihr es versteht, ich kann mein Programm per Mail an ein Testsystem schicken und bekomme dann aktuell noch eine Rückmeldung, dass es nicht funktioniert und ich finde einfach nicht heraus,warum nicht
Der ausgeführte Befehl sieht so aus:
$/tmp/2351414-a.out /tmp/testarchive create 4096 40Um die Fehlersuche einzuschränken habe ich mal den Code auf ein Minimum beschränkt und alles andere auskommentiert:
Im Moment sieht es so aus:
int create(char *pfadVFS, char *groesseBlockString, char *anzahlBloeckeString) { int groesseBlock, anzahlBloecke; int rueckgabe = 0; printf("In create()-Funktion\n"); char *pfadStore = strdup(pfadVFS); char *pfadStructure = strdup(pfadVFS); printf("Pfad kopieren funktioniert\n"); strcat(pfadStore, ".store"); strcat(pfadStructure, ".structure"); printf("Pfad erweitern funktioniert\n"); rueckgabe = validateCreate(pfadStore, pfadStructure, groesseBlockString, anzahlBloeckeString); printf("ValidateCreate funktioniert\n"); if(rueckgabe != 0) { return rueckgabe; } printf("Ende create()-Funktion\n"); return 0; } int validateCreate(char *pfadStore, char *pfadStructure, char *groesseBlockString, char *anzahlBloeckeString) { FILE *dateiStore; FILE *dateiStructure; printf("In validateCreate()-Funktion\n"); dateiStore = fopen(pfadStore, "rb"); dateiStructure = fopen(pfadStructure, "rb"); printf("fopens funktionieren\n"); if(dateiStore != NULL || dateiStructure != NULL) { if(dateiStore != NULL) { printf("store ist nicht null\n"); fclose(dateiStore); } if(dateiStructure != NULL) { printf("structure ist nicht null\n"); fclose(dateiStructure); } printf("Mindestens eine der Dateien des vfs existiert bereits"); return 3; } if(dateiStore == NULL && dateiStructure == NULL) { printf("Beide Dateien sind null und somit noch nicht vorhanden\n"); } printf("Ende validateCreate()-Funktion\n"); return 0; }
sorry falls es so komisch formatiert ist
Also bei der Testabgabe wird ein gültiger Pfad angegeben aber mein Programm fliegt immer beim ersten fopen raus.
Folgender Fehler wird angezeigt:Execution took less than: 0.2 sec. Exit codes do not match: Expected=0 Result=134 stdout: In create()-Funktion Pfad kopieren funktioniert Pfad erweitern funktioniert In validateCreate()-Funktion stderr: *** glibc detected *** /tmp/2351414-a.out: free(): invalid next size (normal): 0x08472038 *** ======= Backtrace: ========= /lib/libc.so.6(+0x6adba)[0xf7618dba] /lib/libc.so.6(+0x6c608)[0xf761a608] /lib/libc.so.6(cfree+0x6d)[0xf761d74d] /lib/libc.so.6(+0x5bbc0)[0xf7609bc0] /lib/libc.so.6(fopen+0x2c)[0xf7609bfc] /tmp/2351414-a.out[0x804a90b] /tmp/2351414-a.out[0x804a8b8] /tmp/2351414-a.out[0x804abc2] /lib/libc.so.6(__libc_start_main+0xe6)[0xf75c4c96] /tmp/2351414-a.out[0x8048881] ======= Memory map: ======== 08048000-0804c000 r-xp 00000000 ca:02 6691211 /tmp/2351414-a.out 0804c000-0804d000 rw-p 00003000 ca:02 6691211 /tmp/2351414-a.out 08472000-08493000 rw-p 00000000 00:00 0 [heap] f7400000-f7421000 rw-p 00000000 00:00 0 f7421000-f7500000 ---p 00000000 00:00 0 f758b000-f75a8000 r-xp 00000000 ca:02 6686170 /lib/libgcc_s.so.1 f75a8000-f75a9000 rw-p 0001c000 ca:02 6686170 /lib/libgcc_s.so.1 f75ac000-f75ae000 rw-p 00000000 00:00 0 f75ae000-f76ec000 r-xp 00000000 ca:02 6686263 /lib/libc-2.11.3.so f76ec000-f76ed000 ---p 0013e000 ca:02 6686263 /lib/libc-2.11.3.so f76ed000-f76ef000 r--p 0013e000 ca:02 6686263 /lib/libc-2.11.3.so f76ef000-f76f0000 rw-p 00140000 ca:02 6686263 /lib/libc-2.11.3.so f76f0000-f76f3000 rw-p 00000000 00:00 0 f76f3000-f7717000 r-xp 00000000 ca:02 6686245 /lib/libm-2.11.3.so f7717000-f7718000 r--p 00023000 ca:02 6686245 /lib/libm-2.11.3.so f7718000-f7719000 rw-p 00024000 ca:02 6686245 /lib/libm-2.11.3.so f771b000-f771e000 rw-p 00000000 00:00 0 f771e000-f771f000 r-xp 00000000 00:00 0 [vdso] f771f000-f773a000 r-xp 00000000 ca:02 6686256 /lib/ld-2.11.3.so f773a000-f773b000 r--p 0001b000 ca:02 6686256 /lib/ld-2.11.3.so f773b000-f773c000 rw-p 0001c000 ca:02 6686256 /lib/ld-2.11.3.so ffd69000-ffd7e000 rw-p 00000000 00:00 0 [stack]
-
Du zerschießt dir den Heap. Höchstwahrscheinlich durch Fehler bei der Zeichenkettenbearbeitung. Ohne komplettes Programm kann man jedoch nicht mit dem Finger auf den genauen Fehler zeigen*. Fühlst du dich sicher beim Verarbeiten von Zeichenketten und bei der Nutzung von dynamischem Speicher? Falls nein: Hier ist der Ansatz zur Lösung des Problems: Grundlagen an einfachen Beispielen lernen.
Unter Linux kannst du mit valgrind einfach und genau die Ursachen solcher Fehler finden, was aber voraussetzt, dass du einigermaßen weißt, wie dynamische Speicherverwaltung richtig geht, damit du die Diagnosemeldungen überhaupt einordnen kannst.
Dein Problem hat nichts mit Linux zu tun, das gezeigte Programm ist vollkommen portabel. Es ist bloß an sich fehlerhaft. Undefiniertes Verhalten kann sich jedoch auf unterschiedlichen Systemen unterschiedlich äußern, unter anderem kann es auch einfach funktionieren.
*: Dies ist keine Aufforderung, uns das komplette Programm zu zeigen! Minimalbeispiel ist das Stichwort. Dritter Link in meiner Signatur.
-
@Sepp
Ich verstehe ehrlich gesagt deine Antwort nicht.
Ich habe den kompletten Programmteil, der damit zu tun hat gepostet. Alle anderen Sachen, die ich nicht gepostet habe sind auch bei mir auskommentiert. Der Fehler muss aus etwas mit dem geposteten Code zu tun haben. In der Main() wird nur noch überprüft ob die Anzahl der Argumente stimmt und dann wird "create()" aufgerufen.Und wie kommst du auf Zeichenkettenverarbeitung? Ja, ich dachte, dass ich darin sicher wäre aber ob es stimmt? Keine Ahnung.
Hier noch der Code aus der Main:
int main(int argc, char *argv[]) { int rueckgabe = 0; if(strcmp(argv[2], "create")==0) { if(argc != 5) { printf("Fehlerhafte Anzahl an Argumenten\n"); rueckgabe = 66; } else { rueckgabe = create(argv[1], argv[3], argv[4]); } } else { perror("Sie haben keinen gueltigen Befehl eingegeben." " Versuchen Sie es nocheinmal."); return 66; } return rueckgabe; }
-
Du hängst mit strcat an einen String an, den du von strdup bekommen hast. Das muss ja knallen.
-
@MFK:
Aha, danke für den Tipp. Könntest du mir vielleicht etwas genauer erklären, warum das knallen muss? Ich meine, beim anhängen selbst knallt es ja nicht.
Kann es sein, dass der String beim erstmaligen belegen quasi initialisiert wird und ein späteres anhängen zuerst funktioniert aber später ein Fehler kommt weil der Speicher quasi willkürlich belegt wurde durch den angehängten Teil?
-
C_Mond schrieb:
Könntest du mir vielleicht etwas genauer erklären, warum das knallen muss?
SeppJ schrieb:
Du zerschießt dir den Heap.
Ich meine, beim anhängen selbst knallt es ja nicht.
SeppJ schrieb:
Undefiniertes Verhalten kann sich jedoch auf unterschiedlichen Systemen unterschiedlich äußern, unter anderem kann es auch einfach funktionieren.
Oder noch viel fieser (und häufiger): Es funktioniert, aber später geht etwas ganz anderes schief, das für sich eigentlich richtig wäre, wenn vorher kein Fehler passiert wäre.
P.S.:
C_Mond schrieb:
Und wie kommst du auf Zeichenkettenverarbeitung? Ja, ich dachte, dass ich darin sicher wäre aber ob es stimmt? Keine Ahnung.
Du hast Probleme mit Zeichenkettenverarbeitung (und damit indirekt auch mit manueller Speicherverwaltung), auch wenn du es nicht wahrhaben möchtest. Daher nochmal der Rat:
SeppJ schrieb:
Fühlst du dich sicher beim Verarbeiten von Zeichenketten und bei der Nutzung von dynamischem Speicher? Falls nein: Hier ist der Ansatz zur Lösung des Problems: Grundlagen an einfachen Beispielen lernen.
Zeichenkettenverarbeitung ist wohl eines der Hauptprobleme für Anfänger in C. Daher ist ihm in guten Büchern (Siehe als wichtig markierte Links im Forum) auch ausführlich erklärt.
-
Okay, ich denke ich habs verstanden. Gehört halt alles zum Lernprozess dazu
Nun gut. Ich bin also nicht sicher in der Zeichenkettenverarbeitung. Wie löse ich nun das Problem mit dem anhängen?
-
C_Mond schrieb:
Nun gut. Ich bin also nicht sicher in der Zeichenkettenverarbeitung. Wie löse ich nun das Problem mit dem anhängen?
Du musst erst einmal verstehen, warum das falsch ist. Ich habe dir oben noch etwas in meine Antwort editiert, während du schon geantwortet hast.
Ansonsten spar ich mir mal Links zu nüchternen technischen Erklärungen wie Wikipedia. Du brauchst didaktisches Lehrmaterial. Hier ein Anfang:
http://www.c-plusplus.net/forum/300567
-
Nach endlosen weiteren Versuchen. Kann mir bitte irgendwer hier im Forum verraten wie man das richtig löst?