Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++ tekstin tallennus

Sivun loppuun

Jyri [17.11.2004 16:54:10]

#

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?

Deewiant [17.11.2004 17:09:20]

#

Ei varmaankaan kannata kirjoittaa tiedostoon ennen kuin käyttäjä käskee tallentaa.

Jyri [17.11.2004 20:16:51]

#

Oho, sähän ootki tosi terävä tyyppi, en ois ees ite tullu ajatelleeks. Pitäskö nää kaikki kysymyksetki muotoilla ku ruotsalaisille?

Aruviel [17.11.2004 20:23:08]

#

Jos asennoituu annettuun neuvoon noin, niin varmaankin kannattaa siirtyä jonnekin muualle vinkumaan apua. Lisäksi kysymyksesi oli harvinaisen epäselvästi muotoiltu.

thefox [18.11.2004 14:40:31]

#

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.

Jyri [18.11.2004 16:42:25]

#

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ä?

thefox [19.11.2004 11:35:09]

#

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;

Metabolix [19.11.2004 17:42:39]

#

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;

Jyri [20.11.2004 08:47:51]

#

Kiitti. Nyt lähti sujumaan :)

Metabolix [20.11.2004 11:41:58]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta