Forum » Programiranje » Datotečni tokovi c++
Datotečni tokovi c++
Adoo ::
Pregledal sem zelo veliko linkov na to temo ampak še vedno mi ni čisto jasna ta tema...
Vem kako odpirati datoteko,zapirati , dodajati,brati besedilo , itd... Ampak kako uporabiš get(), put(),... Naprimer
da doda pred znak ":" v tekstovni datoteki nekaj kar je vpisal uporabnik.
Hvala za odgovore že vnaprej
Vem kako odpirati datoteko,zapirati , dodajati,brati besedilo , itd... Ampak kako uporabiš get(), put(),... Naprimer
da doda pred znak ":" v tekstovni datoteki nekaj kar je vpisal uporabnik.
Hvala za odgovore že vnaprej
Vesoljc ::
te zanima kako nekaj vrinit v datoteko ali kako neko vpisano vrednosti zapisat?
Abnormal behavior of abnormal brain makes me normal...
mallard ::
istream::get()pač prebere podatke iz toka, kolk in kako je odvisno kater overload uporabiš.
ostream::put()pa vpiše en char, s tem da prepiše tisto kar je blo prej na tistem mestu v toku. V tokove se ne da vstavljat tako, da se podatki za tistim mestom, kjer vstavljaš, kar sami premaknejo naprej. Za to morš poskrbet sam.
Če bi prilepu kakšno kodo in pokazal kaj bi rad naredu, bi ti lažje kdo pomagal.
Adoo ::
Tukaj imam npr. eno vajo kateri za začetek hočem spremeniti število pred znakom ":" z številom ki ga je uporabnik vpisal.
Vsebina tekstovne datoteke xfiles je :
1
00:00:09,051 --> 00:00:12,930
CALEDINIA, WISCONSIN
17. NOVEMBER, 1990
2
00:00:30,155 --> 00:00:32,950
Očitno ni nikogar doma.
Koda ki jo imam do zdaj :
Koda mi za zdaj naredi to da karkoli napišem v spremljivko "zamik" se v tekstovni datoteki vse izbriše in shrani le številka 0.
Hvala za pomoč vnaprej!
Vsebina tekstovne datoteke xfiles je :
1
00:00:09,051 --> 00:00:12,930
CALEDINIA, WISCONSIN
17. NOVEMBER, 1990
2
00:00:30,155 --> 00:00:32,950
Očitno ni nikogar doma.
Koda ki jo imam do zdaj :
#include<iostream> #include<fstream> #include<string> using namespace std; int main() { ifstream vhodna_dat; ofstream izhodna_dat; string test; char a[30]; string zamik; string znak; string stevilo; string podnapis; cout<<"Vpisi zamik"<<endl; cin>>zamik; vhodna_dat.open("xfiles.txt"); izhodna_dat.open("xfiles.txt"); while(!vhodna_dat.eof()) { znak=vhodna_dat.get(); if(znak==":") { znak=zamik; } cout<<znak<<endl;} izhodna_dat<<vhodna_dat; izhodna_dat.close(); vhodna_dat.close(); system("pause"); return 0; }
Koda mi za zdaj naredi to da karkoli napišem v spremljivko "zamik" se v tekstovni datoteki vse izbriše in shrani le številka 0.
Hvala za pomoč vnaprej!
mallard ::
V tvoji kodi je cel kup napak. Najprej to, da isto datoteko dodeliš dvema različnima tokovoma:
To ne bo šlo. Če hočeš hkrati brat in pisat v isto datoteko, potem naredi en fstream.
Dalje, tvoja while zanka:
Problem s tem je, da eof() funkcija ni zanesljiva. Zgodilo se bo, da bo vrnila true šele ko boš poskusu brat preko konca datoteke, kar pomeni, da boš bo v zanko vstopil enkrat preveč. Ko bereš iz nekega toka in potem nekaj delaš s prebranimi podatki, se moraš prej prepričat da je branje uspelo. Npr. takole:
Kako to deluje? Rezultat operatorja operatorja>> je referenca na tok iz katerega si klical ta operator. Če ta rezultat uporabiš v bool kontekstu (torej v pogoju za if ali while stavek, ipd.) se implicitno pretvori v bool tip - v true, če je branje uspelo in v false, če ni. (več si lahko prebereš tu: http://www.parashift.com/c++-faq-lite/i...)
Dalje:
To ne dela tistega, kar misliš, da dela. Noben od overloadov ne vzame drugega toka kot argument. V tvojem primeru se vhodna_dat implicitno pretvori v void* kazalec, v izhodna_dat se pa zapiše vrednost tega kazalca (0 če je tok v enem od fail(), eof(), ali badbit() stanju oziroma neka pozitivna vrednost če ni). Če res rabiš celotno vsebino toka zapisat v drug tok, bi rekel takole:
To je v grobem, kar delaš narobe. Jaz bi se drugač lotil tvojga problema. Šel bi skozi vhodno datoteko vrstico po vrstico in potem popravljene vrstice zapisoval v drugo, izhodno datoteko. Nekak v tem smislu:
vhodna_dat.open("xfiles.txt"); izhodna_dat.open("xfiles.txt");
To ne bo šlo. Če hočeš hkrati brat in pisat v isto datoteko, potem naredi en fstream.
Dalje, tvoja while zanka:
while(!vhodna_dat.eof())
Problem s tem je, da eof() funkcija ni zanesljiva. Zgodilo se bo, da bo vrnila true šele ko boš poskusu brat preko konca datoteke, kar pomeni, da boš bo v zanko vstopil enkrat preveč. Ko bereš iz nekega toka in potem nekaj delaš s prebranimi podatki, se moraš prej prepričat da je branje uspelo. Npr. takole:
int i = 0; if (cin >> i) { // naredi nekaj z i }
Kako to deluje? Rezultat operatorja operatorja>> je referenca na tok iz katerega si klical ta operator. Če ta rezultat uporabiš v bool kontekstu (torej v pogoju za if ali while stavek, ipd.) se implicitno pretvori v bool tip - v true, če je branje uspelo in v false, če ni. (več si lahko prebereš tu: http://www.parashift.com/c++-faq-lite/i...)
Dalje:
izhodna_dat<<vhodna_dat;
To ne dela tistega, kar misliš, da dela. Noben od overloadov ne vzame drugega toka kot argument. V tvojem primeru se vhodna_dat implicitno pretvori v void* kazalec, v izhodna_dat se pa zapiše vrednost tega kazalca (0 če je tok v enem od fail(), eof(), ali badbit() stanju oziroma neka pozitivna vrednost če ni). Če res rabiš celotno vsebino toka zapisat v drug tok, bi rekel takole:
izhodna_dat << vhodna_dat.rdbuf();
To je v grobem, kar delaš narobe. Jaz bi se drugač lotil tvojga problema. Šel bi skozi vhodno datoteko vrstico po vrstico in potem popravljene vrstice zapisoval v drugo, izhodno datoteko. Nekak v tem smislu:
#include <fstream> #include <string> using namespace std; int main() { // datotečne tokove lahko odpreš direktno v konstruktorjih, ni treba posebej klicat .open() ifstream vhodna_dat("xfiles.txt"); ofstream izhodna_dat("xfiles_2.txt"); if (!vhodna_dat.is_open() || !izhodna_dat.is_open()) { // ene od datotek ni blo mogoče odpret return 1; } string vrstica; while (getline(vhodna_dat, vrstica)) { // za getline velja isto, kot sem zgoraj napisal za operator>> // zanimajo nas samo vrstice, ki niso prazne in ki vsebujejo podatke o času za podnapis if (vrstica.length() > 0 && vrstica.find("-->") != string::npos) { // tukaj popravimo čase itd. } // getline spusti znake za novo vrstico ('\n') ko bere iz vhodne datoteke, zato // jih mormo pri pisanju vnest mi izhodna_dat << vrstica << '\n'; } // ni ti treba eksplicitno klicat .close() na tokovih, zaprejo jih destruktorji, ko se konča // okvir v katerem so definirani (oz. kakorkol se že reče "go out of scope" po slovensk :)) }
Zgodovina sprememb…
- spremenilo: mallard ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [c] Enaki datotekiOddelek: Programiranje | 1042 (902) | Spura |
» | C osnovaOddelek: Programiranje | 1563 (1078) | RunoTheDog |
» | [C++][Naloga] Tekstovne datoteke, realna številaOddelek: Programiranje | 4056 (3672) | Gundolf |
» | [C++][Naloga_polja]MIN in MAX polja, izpis za x.100 stevilOddelek: Programiranje | 2947 (2758) | snow |
» | obratno izpiši besedi - c++Oddelek: Programiranje | 1771 (1602) | losnah |