Zeile in einer Datei editieren (ich schon wieder...)
-
Wow bist Du schnell!
Kannst Du mir da CODE-mässig ein bisl unter die Arme greifen? Bin doch noch so'n NOOB...
-
dazu brauchst du dynamische speicherverwaltung.
#define BUFFSIZE 512 char **ppLines = NULL; char buffer[BUFFSIZE]; int nElements=0;
Einlesen:
while (fgets(buffer, BUFFSIZE, fp) != NULL) { nElements++; // speicher für das pointerarray allokieren ppLines = (char**) realloc (ppLines, nElements*sizeof(char*)); // speicher für den string allokieren ppLines[nElements-1] = (char*) malloc ((strlen(buffer)+1)*sizeof(char)); strncpy(ppLines[nElements-1], buffer, strlen(buffer)); }
Dann arbeite mit den Datensätzen und schreibe sie wieder in datei
am ende freigeben nicht vergessen
if (ppLines) { for (int i=0; i<nElements; i++) { if (ppLines[i]) { free (ppLines[i]); ppLines[i] = NULL; } } free (ppLines); ppLines = NULL; }
-
"fp" in fgets ist der Verweis auf meine Datei, richtig??
Sieht ja alles schon ganz gut aus... Kannst Du mir noch zeigen, wie ich dann in den Daten rumschreiben kann und das ganze dann in die Datei zurückschreiben kann??
Ich versteh zwar was Du mir da gepostet hast, aber ich würde nie selber auf sowas kommen...
Danke!!!
-
Doom5000 schrieb:
"fp" in fgets ist der Verweis auf meine Datei, richtig??
Richtig
Doom5000 schrieb:
Ich versteh zwar was Du mir da gepostet hast, aber ich würde nie selber auf sowas kommen...
das glaub ich dir nicht
was machst du den mit deiner funktion fwrite()?
habe mir gerade noch mal deinen post angeschaut, glaubst du nicht es ist besser alles in eine Struktur zu packen?
-
fwrite schreibt mir eine Zeile in die Datei. Aber eben unten dran...
Ich bin jetzt schon soweit, dass er den dynamischen Speicher richtig aufbaut, dann die richtige Zeile raussucht, jetzt muss ich nur noch das mit dem Überschreiben hinkriegen. Insgesamt scheint das aber zu klappen!
Wenns läuft werde ich das hier nochmal posten, vielleicht kann man dann ja noch das ein oder andere "hübsch" machen...
-
wie kann ich denn vor dem schreiben am besten die Datei wieder ganz leer machen?? Ich hab schon die verschiedenen Modes beim fwrite durchprobiert aber ich bekomm immer noch so komisches Zeug vor meinen eigentlichen Werten. Das Überschreiben an sich scheint aber zu funktionieren...
ÏÝ»ÌÛ þ/Ï›œË¾‘ÛŒÿ/Ϝ˾‘Û?yÒÿèþ/ùœ’ÝÓÍïú/Ϥ™ÀÀ’Üüü/Ϟ¸Á‘Ú¿ý/Ï‹œÍ”Ø?yÒÿµû/ùÝ› Òÿµû/ùÝ›œŒÝÓ¯ø/ÏÝ›ÁÄœÚù/Ïœ–Á˘Ûÿý/Ïš‘ƾÛ?yÒÿØþ/ùÝ”’“ÝÓßú/Ïš‘¶Ä’ÛŸü/Ï—£¶»‰ßŸþ/Ï 02 WOO.V \ QB03 Q W ` f lumme ]VR0508002 020000 000000 ‡ áÒN‡ep Tÿ ð€ ðoï ð À £‡oï ðoï ðoï ðoï ðš áÒep \‡Mø ðÍÎI‡9ç ð:ÈéÎ( ì†ì÷P&ÿw&ÿwšÿÿ †ì÷ŒVþ‰Fü‹Fþ‹Vü‰Fú‰Vø3öé¨ ÿvþÿvü¸~ Pšÿÿ ‰Vú‰FøFúué‹ Ä^ø&Æ †Ò÷ QB0306004 001000 5500 0 4 Testblatt Zeile:1 Spalte:1 Nummer:1 (ENDE) VQ0577000 009000 000000 1 4 Testblatt Zeile:1 Spalte:2 Nummer:2 VR0508002 020000 000000 0 5 Testblatt Zeile:1 Spalte:3 Nummer:3 QB0306003 100000 000000 0 6 Testblatt Zeile:2 Spalte:1 Nummer:4 VQ0576000 900000 000000 1 6 Testblatt Zeile:2 Spalte:2 Nummer:5
-
habs schon....
mit "wt+" hats gut geklappt!
-
So, das funktioniert jetzt alles schon ziemlich gut. Problematisch wirds aber, wenn ich meine Original-Zählerdatei teste: Sie hat knapp 1000 Zeilen, womit diese dynamische Speicherverwaltung anscheinend nicht klarkommt... Kann man das irgendwie noch aufbohren, oder muss ich das anders machen?
Die ganze Geschichte funktioniert, aber um die richtige Nummer im Speicher zu finden braucht er gut 2 Minuten... (auf dem Handheld)
Gibts da noch irgendeine andere Möglichkeit das zu realisieren??
Hier nochmal der aktuelle Code:
(nur die collect_data-Funktion)void collect_data(void) { #define BUFFSIZE 90 int ks, rc; /* ks=Keystroke, rc=ReturnCharacter */ int collect_flag = 1; char file_buffer[95]; /* Puffer fr die Daten aus der Datei */ char **ppLines = NULL; char buffer[BUFFSIZE]; int nElements = 0; int i; char zSuch_buffer[10]; //Puffer zum Speichern der gesuchten Z-Nr. while(collect_flag) { memset(zNr,0,sizeof(zNr)); /* Variablen werden mit Nullwerten gefllt */ memset(oldStd,0,sizeof(oldStd)); memset(newStd,0,sizeof(newStd)); memset(ueber,0,sizeof(ueber)); memset(anzSt,0,sizeof(anzSt)); memset(einbau,0,sizeof(einbau)); inv_menu(); // Inventurmen zeigen rc = get_scan_input(zNr,10,7,1,0); // Nummer einlesen if(rc == -1) // ESC wurde gedrckt { collect_flag = 0; break; } trim_spaces(zNr); if(*zNr) { if((inv_file = fopen(INVFILE, "r")) == NULL) { clrscr(); gotoxy(2,1); printf("Dateifehler"); delay(1000); } if(lookup()) /* Nummer in der Datei suchen Variablen setzen */ { // Z-Nummer gefunden, Daten ausgeben: gotoxy(14,2); printf("%s",oldStd); gotoxy(10,4); printf("%s", anzSt); if(strcmp(ueber,"1") == 0) //šberlauf anzeigen { gotoxy(13,4); printf("šberlauf"); } gotoxy(1,6); printf("%s",einbau); gotoxy(14,3); shift_lock(1); //Aufbau des dynamischen Speichers fseek(inv_file, 0, SEEK_SET); nElements = 0; while(fgets(buffer, BUFFSIZE, inv_file) != NULL) { nElements++; //Speicher fr Pointerarray allokieren ppLines = (char**) realloc (ppLines, nElements*sizeof(char*)); //Speicher fr den String allokieren ppLines[nElements-1] = (char*) malloc ((strlen(buffer)+1)*sizeof(char)); strncpy(ppLines[nElements-1], buffer, strlen(buffer)); } if(strcmp(newStd, "000000") != 0) // Neuer ZS wurde schon eingegeben: { gotoxy(14,3); printf("%s", newStd); gotoxy(14,3); // evtl. Editieren des neuen Standes: ks = dgetch(NOECHO); if(ks == ESC || ks == BS) { // Abbruch durch ESC oder BkSp } else { // Neuen ZS annehmen: memset(newStd,0,sizeof(newStd)); gotoxy(14,3); printf(" "); get_kybrd_input(newStd,7,14,3,NUMLOCK); for(i=0; i<nElements;i++) { //Z„hlernummer zum Suchen kopieren strncpy(zSuch_buffer, ppLines[i], 9); //9 Zeichen der Zeile in den Buffer zSuch_buffer[9] = '\0'; if(strcmp(zNr, zSuch_buffer) == 0) { //Zeile im Speicher erneuern sprintf(ppLines[i],"%-10s%-7s%-7s%-2s%-2s%-61s", zNr, oldStd, newStd, ueber, anzSt, einbau); } } } }//Ende von If "ZS lag schon vor" else // Neuer ZS liegt noch nicht vor: { memset(newStd,0,sizeof(newStd)); // Eingabe des neuen Standes get_kybrd_input(newStd,7,14,3,NUMLOCK); //richtige Zeile suchen for(i=0; i<nElements;i++) { //Z„hlernummer zum Suchen kopieren strncpy(zSuch_buffer, ppLines[i], 9); //9 Zeichen der Zeile in den Buffer zSuch_buffer[9] = '\0'; if(strcmp(zNr, zSuch_buffer) == 0) { //Zeile im Speicher erneuern sprintf(ppLines[i],"%-10s%-7s%-7s%-2s%-2s%-61s", zNr, oldStd, newStd, ueber, anzSt, einbau); } } }//Ende von Else "ZS lag noch nicht vor" //Datei erstmal wieder zu machen fclose(inv_file); //Datei mit anderem Mode wieder aufmachen if((inv_file = fopen(INVFILE, "wt+")) == NULL) { clrscr(); gotoxy(2,1); printf("Dateifehler"); delay(1000); } // Zurckschreiben in Datei: for(i=0; i<nElements; i++) { fwrite(ppLines[i],88,1,inv_file); fputs("\n",inv_file); } //OutFile dicht machen fclose(inv_file); //dynamischen Speicher wieder freigeben if(ppLines) { for(i=0; i<nElements; i++) { if(ppLines[i]) { free(ppLines[i]); ppLines[i] = NULL; } } free(ppLines); ppLines = NULL; } }//Ende von If "Z-Nummer gefunden" else // Z„hlernummer nicht in Datei vorhanden { clrscr(); gotoxy(3,3); printf("nicht gefunden..."); delay(1500); } }//Ende von if(*zNr) }// Ende von while(collect_flag) }//Ende von collect_data()
-
MOIN!
so, bin jetzt schon mal ne ganze Ecke weiter: Ich lasse den dyn. Speicher jetzt einfach am Anfang der Routine einmal erzeugen, dann wird damit gearbeitet beim Verlassen der Funktion wird dann alles zurück in die Datei geschrieben.
Dieses Zurückschreiben dauert allerdings SEHR lange auf meinen Handhelds... (Ca. 4 min)
Kann man das irgendwie noch schneller lösen?? Das Einlesen der Datei dauert auch nur ein paar Sekunden...So wirds bei mir zurückgeschrieben:
if((inv_file = fopen(INVFILE, "wt+")) == NULL) { clrscr(); gotoxy(2,1); printf("Dateifehler"); delay(1000); } // dyn. Speicher zurückschreiben in Datei: for(j=0; j<nElements; j++) { fwrite(ppLines[j],88,1,inv_file); fputs("\n",inv_file); clrscr(); gotoxy(1,1); printf("Datei wird geschrieben\n"); printf("Zähler-Nr.: %d", j); } //File dicht machen fclose(inv_file);
-
gibst du den speicher auch wieder frei?
-
Ja, der Speicher wird beim Beenden des Programmes wieder freigegeben. Dies erfolgt erst so spät, weil ich für andere Bereiche der Anwendung die Daten auch noch brauche. Funktioniert bis jetzt auch alles prima. Im Prinzip kann man damit jetzt schon ganz gut arbeiten. Das Rückschreiben in die Datei ist zwar etwas nervig, aber man kann sich darauf einstellen.
Falls jemand noch Verbesserungsvorschläge hat, gerne her damit...
Chris
Dies erfolgt am Ende der Main-Methode:
// dynamischen Speicher wieder freigeben if(ppLines) { for(j=0; j<nElements; j++) { if(ppLines[j]) { free(ppLines[j]); ppLines[j] = NULL; } } free(ppLines); ppLines = NULL; }