Eli olen tekemässä txt editroia Konsoliin.
Ongelmanin on tekstin tallentaminen.
Osaan tehdä, niin, että yksi rivi kirjoitetaan txt filuun, mutta miten saisin kirjoitettua monta riviä sinne?
Eli kannattaako minun tehdä vaikka taulukko jossa on 50 alkiota ja lukea jokaiseen alkioon aina yksi kirjain tekstin loppuun asti vai kannattaako lukea käyttäjän teksti puskuriin rivi kerrallaan ja kirjoittaa aina sen jälkeen filuun?
Ei varmaankaan kannata kirjoittaa tiedostoon ennen kuin käyttäjä käskee tallentaa.
Oho, sähän ootki tosi terävä tyyppi, en ois ees ite tullu ajatelleeks. Pitäskö nää kaikki kysymyksetki muotoilla ku ruotsalaisille?
Jos asennoituu annettuun neuvoon noin, niin varmaankin kannattaa siirtyä jonnekin muualle vinkumaan apua. Lisäksi kysymyksesi oli harvinaisen epäselvästi muotoiltu.
Tuo nyt riippuu ihan siitä miten sinä sitä käyttäjän kirjoittamaa tekstiä pidät muistissa. Tiedostoon kirjoittaminen itsessään on helppo homma.
Muotoile kysymys uudelleen ja kerro tarkemmin, minkälainen se tämänhetkinen systeemi on.
Joo, täytyy myötää, että kysymys on mahdollisimman epäselvä. Eli ongelmana on se, että miten tekstiä kannattaa pitää muistissa.
Eli kannattaako teksti lukea merkki kerrallaan taulukkoon ja kirjoittaa sieltä filuun, vai miten kannattaisi tehdä?
Jos teet ihan simppelin editorin niin pidä koko tiedostoa vaan muistissa kunnes käyttäjältä käy käsky sen kirjoittamiseksi. Jos haluat, että editorisi kykenee käsittelemään myös suuria tiedostoja, voisi jonkinlainen oma swappisysteemi olla hyödyllinen.
Toivottavasti dynaaminen muistinvaraus on sinulle tuttua. Kannattanee pitää nykyinen muistin koko jossain muuttujassa, esim.
unsigned long mem_amount = 256; char *mem;
Ohjelman alussa allokoit (esim. new:llä) tuon verran muistia, ja lueskelet käyttäjältä tavaraa sinne ihan normaalisti. Kun muistin raja mem_amount tulee vastaan, tulee sinun kasvattaa taulukon kokoa. Usein koko kasvatetaan kaksinkertaiseksi. Tämän voi tehdä esimerkiksi niin, että varaa uuden lohkon (jonka koko on siis kaksinkertainen), ja kopioi tavarat vanhasta lohkosta sinne. Sitten vain vapautetaan vanha lohko ja laitetaan pointteri osoittamaan uuteen lohkoon.
Eli jotain tällaista:
char *tmp = new char[mem_amount * 2]; memcpy(tmp, mem, mem_amount * sizeof(char)); delete[] mem; mem = tmp; mem_amount *= 2;
Itse käyttäisin (malloc- ja free- sekä) realloc-funktioita ja lisäisin muistin määrään aina saman verran (isoja tiedostoja huomioiden):
// Liitetään stdlib.h ja määritellään muistin kertalisäyksen koko #include <stdlib.h> const LISAYS = 1024; // kilotavu // Luodaan ja nollataan muuttujat char *Buf = 0; int Mem_Amount = 0; //======================= // Varataan lisää muistia. 1. kerralla myös malloc-funktio toimisi Buf = realloc(Buf, Mem_Amount + LISAYS); // Tyhjennetään bufferin loppupuoli varmuuden vuoksi memset(&Buf[Mem_Amount], 0, LISAYS); // Merkitään uusi muistimäärä Mem_Amount += LISAYS; //======================= // Vapautetaan muisti. Myös free-funktio kelpaisi. Buf = realloc(Buf, 0); Mem_Amount = 0;
Kiitti. Nyt lähti sujumaan :)
Heitetäänpä peliin vielä semmoinen vihje, että jos et halua määritellä rivin maksimipituutta ja varata joka riville sitä määrää muistia, voi olla varteenotettava idea toteuttaa tuo homma jotenkin rivi kerrallaan taulukkona tai linkitettynä listana. Nyt nimittäin voit joutua siirtämään merkkejä mielettömän määrän eteenpäin, jos joku kirjoittaa lisää esim. tiedoston alkuun. Olisi varmasti nopeampaa, jos tarvitsisi siirtää vain saman rivin merkkejä, ja uuden rivin lisääminen johonkin väliin olisi myös helpompaa, ainakin kaksoislinkitetyllä listalla.
Aihe on jo aika vanha, joten et voi enää vastata siihen.