Tiedosto on yhteenkuuluvien tietojen joukko, joka tavallisimmin sijaitsee kiintolevyllä, muistitikulla tai jollakin muulla fyysisellä tietovälineellä.



Samankaltaiset tiedostot
Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot

Tietueet. Tietueiden määrittely

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Ohjelmoinnin perusteet Y Python

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

// // whiledemov1.c // #include <stdio.h> int main(void){ int luku1 = -1; int luku2 = -1;

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

Binäärioperaatiot Tiedostot ja I/O

Moduli 5: Kehittyneitä piirteitä

C-ohjelmointi, syksy 2006

C-ohjelmointi, syksy Yksiulotteiset taulukot Moniulotteiset taulukot Dynaamiset taulukot. Binääritiedostot. Luento

Ohjelmoinnin perusteet Y Python

Binäärioperaatiot Tiedostot ja I/O

Luennon sisältö. Taulukot (arrays) (Müldnerin kirjan luku 10) Yksiulotteiset taulukot. Mikä taulukko on? Taulukko-osoitin. tavallinen osoitin

Ohjelmoinnin perusteet Y Python

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Tiedosto. Tiedostot ovat joko binääritiedostoja tai tekstitiedostoja. Tekstitiedostot

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

Ohjausrakenteet. Valinta:

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Ohjelmoinnin perusteet Y Python

Lyhyt kertaus osoittimista

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

#include <stdio.h> // io-toiminnot. //#define KM_MAILISSA int main( ){

C-kieli mahdollistaa hyvin tiiviin ja samalla sekavan tavan esittää asioita, kuitenkin hyvän ohjelman tulisi olla mahdollisimman helppolukuinen ja

Java-kielen perusteet

Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla:

Java-kielen perusteet

Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö C-ohjelmassa

Loppukurssin järjestelyt

2. C-kieli ja ongelmanratkaisu

Loppukurssin järjestelyt C:n edistyneet piirteet

Luennon sisältö Tyypit int, char, float, double signed, unsigned short, long Vakiot const Rakenteet if, for, while, switch, do-while Syöttö ja tulostu

Tietorakenteet ja algoritmit

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 6: Python

Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta.

Tietotyypit ja operaattorit

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Ohjelmoinnin perusteet Y Python

TIETORAKENTEET JA ALGORITMIT

Ohjelmoinnin perusteet Y Python

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Ohjelmoinnin peruskurssi Y1

Java-kielen perusteita

Rakenteiset tietotyypit Moniulotteiset taulukot

1. Mitä seuraava ohjelma tulostaa? Vastaukseksi riittää yksi rivi joka esittää tulosteen. (6 p)

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Ohjeet. AS C-ohjelmoinnin peruskurssi Aalto-yliopiston sahkotekniikan korkeakoulu Tentti , Raimo Nikkila

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Ohjelmointiharjoituksia Arduino-ympäristössä

Ohjelmoinnin perusteet Y Python

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Muuttujien roolit Kiintoarvo cin >> r;

Harjoitustyö: virtuaalikone

C-kurssi kevät Luennon sisältö

Luennon sisältö. C-kurssi kevät Tasokokeen kohta 1: Taulukon järjestäminen. Tasokokeen kohta 2. Tasokokeen kohta 2. Tasokokeen kohta 3

13 Operaattoreiden ylimäärittelyjä

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

1.1 Pino (stack) Koodiluonnos. Graafinen esitys ...

Kirjoita, tallenna, käännä ja suorita alla esitelty ohjelma, joka tervehtii käyttäjäänsä.

Osoitin ja viittaus C++:ssa

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

Johdatus ohjelmointiin / Lausekielinen ohjelmointi 1 & 2

ATK tähtitieteessä. Osa 4 - IDL input/output. 19. syyskuuta 2014

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Ohjelmoinnin perusteet Y Python

if-lauseen yksinkertaisin muoto on sellainen, missä tietyt lauseet joko suoritetaan tai jätetään suorittamatta.

Ohjelmoinnin perusteet Y Python

Modulaarisessa ohjelmoinnissa jaetaan ohjelma osiin (moduuleihin), jotka ovat yksinkertaisia ja lyhyitä.

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Tietorakenteet ja algoritmit

Ohjelmoinnin perusteet Y Python

Osoittimet ja taulukot

C-kurssi syksy ltö. Luennon sisält. Luento 2: tyypit, rakenteet, makrot Tyypit. signed, unsigned short,, long Vakiot const Rakenteet

Luennon sisält. ltö. C-kurssi syksy ääreet: int ja char. Yksinkertaiset tyypit. Kokonaisluvut. Merkit

3. Binääripuu, Java-toteutus

Harjoitus 5 (viikko 48)

Osoittimet. Mikä on osoitin?

Tietorakenteet ja algoritmit

12. Näppäimistöltä lukeminen 12.1

Moduli 2: Osoittimet ja taulukot. Joel Huttunen

Moduli 4: Moniulotteiset taulukot & Bittioperaatiot

Luento 5. Timo Savola. 28. huhtikuuta 2006

Ohjelmoinnin perusteet Y Python

Tietorakenteet ja algoritmit

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

Ohjelmoinnin perusteet Y Python

C-ohjelmointi: Osoittimet

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

14. Hyvä ohjelmointitapa 14.1

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

TAITAJA 2007 ELEKTRONIIKKAFINAALI KILPAILIJAN TEHTÄVÄT. Kilpailijan nimi / Nro:

1. luento. Ohjelmointi (C) T0004 Syksy luento. 1. luento. 1. luento. 1. luento. kurssin sisältö ja tavoitteet työmuodot.

5.6. C-kielen perusteet, osa 6/8, Taulukko , pva, kuvat jma

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Ohjelmoinnin perusteet Y Python

Sisältö. 22. Taulukot. Yleistä. Yleistä

Transkriptio:

Tiedostot Tiedosto on yhteenkuuluvien tietojen joukko, joka tavallisimmin sijaitsee kiintolevyllä, muistitikulla tai jollakin muulla fyysisellä tietovälineellä. C-kielessä syöttö ja tulostus kuvataan laiteriippumattomasti abstraktilla tietovirralla (data stream). Tietovirta kuvaa laitteita kuten päätettä, näppäimistöä tai levytiedostoa. 463

Tietovirtoja on kahdenlaisia tekstimuotoisia binäärimuotoista 464

Tekstitiedostot Tekstitiedosto sisältää ASCII-merkkejä, joista muodostetaan yhtä tekstiriviä kuvaavia jonoja, jotka erotetaan toisistaan rivinvaihtomerkillä '\n' (newline). Rivi voi olla tyhjä, mutta silloinkin perässä on rivinvaihtomerkki (riippuu ympäristöstä: Windows/UNIX, tarvitaanko viimeisen rivin lopussa rivinvaihtomerkkiä). 465

Esimerkiksi tekstitiedostosta Tässä<return> on<return> 3 riviä <tiedoston lopetus> Ohjelma näkee tiedoston tietovirtana Tässä\non\n3 riviä<eof> Jokainen rivinvaihto lisää merkin '\n' ja tiedoston loppuun lisätään tunnus EOF (End Of File) merkiksi tiedoston loppumisesta. 466

Tekstitiedoston sisältökin on binäärisessä muodossa, mutta ohjelmat tulkitsevat niiden sisällön eri tavalla. Jos tekstitiedostoon talletetaan luku 593, ei lukua talleteta yhtenä binäärilukuna. Luku talletetaan siten että luvun jokainen symboli talletetaan erillisenä merkkinä '5', '9' ja '3'. Merkit talletetaan ASCII-koodeina '53', ' 57' ja '51'. 467

Koodit muunnetaan ennen lopullista talletusta binäärisiksi '5' -> 53 10 -> 00110101 2 '9' -> 57 10 -> 00111001 2 '3' -> 51 10 -> 00110011 2 Tiedoston sisältö olisi nyt: 001101010011100100110011<EOF> '5' '9' '3' 468

Tekstitiedostoa voidaan käsitellä myös binääritiedostona esimerkiksi kopioitaessa tiedoston sisältö toiseen tiedostoon. Binääritiedostoa ei voi käsitellä tekstitiedostona, tekstiedostojen käsittelyohjelmat eivät osaa tulkita sisältöä oikealla tavalla ja tuloksena on "siansaksaa". Esimerkiksi Unix/Linux -komennolla less voidaan tulostaa valitun tekstitiedoston sisältöä kuvaruudulle. Jos ohjelmalla yrittää avata suoritettavaa ohjelmatiedostoa (=binääritiedosto), ohjelma ilmoittaa käyttäjälle että "tiedosto voi olla binäärimuotoista, katsotaanko kuitenkin?" Tuloksena on tällaista: 469

470

Tiedostojen käsittely voi olla peräkkäiskäsittelyä, jossa ohjelman on luettava tiedostoa sen alusta alkaen vaikka tarvittava tieto sijaitsisi tiedoston lopussa. suorasaantityyppistä, jolloin on mahdollista hakea tietty paikka tiedostosta, tarvitsematta lukea kaikkea edellä olevaa tietoa. 471

Tiedoston käsittelemiseksi ohjelmassa tarvitaan tiedoston osoitin, joka kertoo ohjelmalle tiedoston sijainnin (osoitteen). Tiedoston osoitin viittaa tiedoston kuvaajaan, joka on tyyppiä FILE. FILE -tietorakenne on kuvattu tiedostossa stdio.h. 472

FILE -tietorakenne sisältää mm: tiedosto-osoittimen, joka osoittaa tiedostossa paikkaa, johon seuraava tiedostonkäsittelyoperaatio kohdistuu osoittimen puskurialueeseen indikaattoreita, jotka kertovat mm. onko tapahtunut syöttö- tai tulostusvirheitä ja onko tiedosto loppunut Puskurialue on tietoalue (keskusmuistissa), jonne tiedoston tiedot väliaikaisesti tallentuvat tiedostoa luettaessa tai tiedostoon kirjoitettaessa. Puskurialueen käyttö nopeuttaa tiedostojen käsittelyä, koska 473

keskusmuisti on nopeampaa kuin esimerkiksi kiintolevy. Tiedoston osoitin -muuttuja määritellään FILE *tiedosto; Ennen kuin tiedostoa voidaan käyttää kirjoittamiseen tai lukemiseen on tiedosto avattava fopen -funktiolla. Avaamisessa tietovirta liitetään ulkoiseen tiedostoon. Yleinen muoto: FILE * fopen (const char tiednimi, const char "moodi"); Esimerkki. Seuraavat lauseet määrittelevät kaksi muuttujaa, jotka ovat osoittimia FILE -tietorakenteeseen ja avaavat tiedostot 474

käsittelyä varten. FILE * infilep; FILE * outfilep; intfilep = fopen ( "c:\\data.txt", "r"); outfilep = fopen ( "c:\\results.txt", "w"); Windows/Dos-ympäristössä voidaan tiedoston nimen määrittelyn yhteydessä määritellä koko hakemistopolku ('\'- merkki on kuitenkin annettava kaksinkertaisena '\\'). Unix/Linux ympäristössä hakemistoerotin on '/' ja sitä ei tarvitse antaa kaksinkertaisena. Lisäksi levyasematunnuksia ei ole kuten Windows -maailmassa. 475

FILE * infilep; FILE * outfilep; intfilep = fopen ( "Users/ilkka/demot/data.dat", "r"); outfilep = fopen ( "Users/ilkka/demot/results.dat", "w"); Tiedoston osoittimen tyyppi FILE * (huomaa isot kirjaimet), fopen palauttaa osoittimen muistialueeseen, joka toimii puskurina. 476

Muuttuja intfilep osoittaa puskurialueeseen, jonne on luettu tekstiä tiedostosta data.txt (tai data.dat). Tiedosto on avattu lukemista varten (r = read). Muuttuja outfilep osoittaa puskurialueeseen, jonne tiedostoon results.txt (tai results.dat) talletettavaksi tarkoitettu teksti ensin talletetaan ja josta se myöhemmin kirjoitetaan tiedostoon, joka on avattu kirjoittamista varten ( w = write ). Tiedostoja käsitellään tämän jälkeen muuttujien intfilep ja outfilep avulla. 477

Jos tiedostojen avaus jostakin syystä epäonnistuu, palauttaa fopen arvon NULL. NULL on symbolinen vakio, joka on määritelty stdio.h - kirjastossa, tämä on eri kuin merkkijonon lopetusmerkki '\0' (NUL) Tiedoston c:\\data.txt (tai Users/ilkka/demot/data.dat) avauksen onnistuminen on testattava ennen kuin tiedostoa aletaan käsitellä. if ( infilep == NULL ) printf("virhe tiedoston a:\data.txt avaamisessa\n"); 478

Tiedostojen sisällön käsittelyyn vastaavat funktiot kuin tavalliseen I/O-käsittelyyn. tavallinen I/O tiedosto I/O scanf ("%d", &luku); fscanf(infilep, "%d", &luku); printf("luku=%d\n",luku); fprintf(outfilep,"arvo=%d\n",luku); ch = getchar(); ch = fgetc(infilep); putchar(ch); fputc(ch, outfilep); 479

Tiedostot on käsittelyn lopuksi suljettava funktiolla fclose. tiedosto voidaan avata myöhemmin samassa ohjelmassa uudelleen, jos tarve vaatii fclose vapauttaa tiedoston puskurialueelle varatun tilan ja kirjoittaa puskurin sisällön tiedostoon, jos tietoa ei vielä ole talletettu. fclose (infilep); fclose (outfilep); 480

Tekstitiedoston käsittelyssä voidaan erottaa kolme eri tyyliä merkeittäin: fgetc, fputc riveittäin: fgets, fputs formatoidusti: fscanf, fprintf 481

Esimerkkiohjelma, joka kopioi tekstitiedoston #include <stdio.h> #define KOKO 80 int main ( void ) { char inname[koko], outname[koko]; /* nimet */ FILE *inp, *outp; int ch; /* merkin ASCII-koodin lukemiseen */ printf("\nanna kopioitavan tiedoston nimi >"); scanf("%s",inname); if( (inp=fopen(inname, "r")) == NULL){ printf("tiedoston %s avaaminen lukemista varten epäonnistui\n", inname); return 0; } 482

printf("\nanna kopiotiedoston nimi >"); scanf("%s", outname); outp = fopen(outname, "w"); for ( ch = fgetc( inp ); ch!= EOF; ch = fgetc ( inp )){ fputc ( ch, outp); } } fclose( inp ); fclose( outp ); printf("\nkopioitiin tiedosto %s tiedostoksi %s\n", inname, outname); return ( 0 ); 483

484

Tiedoston avauksessa olennaista avausmoodi r avaa olemassa olevan tiedoston lukemista varten w luo uuden tiedoston kirjoitusta varten, jos tiedosto on jo olemassa, tuhoutuu sen vanha sisältö a avaa olemassa olevan tiedoston lisäämistä varten, jos tiedostoa ei ole se luodaan r+ avaa olemassa olevan tiedoston sekä lukemista että kirjoitusta varten w+ avaa tiedoston lukemista ja kirjoittamista varten, jos tiedosto on jo olemassa, tuhoutuu sen vanha sisältö a+ avaa olemassa olevan tiedoston sekä lukemista että lisäämistä varten, jos tiedostoa ei ole niin se luodaan. 485

Esimerkkifunktio, joka ylläpitää asiakkaiden tilitietoja tekstitiedostossa tilinumero nimi saldo Suunnittelussa on otettava huomioon miten tiedostossa erotetaan toisistaan tilinumero, nimi, saldo ja miten eri tilirivit erotetaan toisistaan. 486

Esiteltävässä ohjelmassa tilinumero erotetaan nimestä välilyönnillä ja nimi erotetaan saldosta välilyönnillä tilirivit erotetaan toisistaan rivinvaihdolla '\n' eli tiedosto on muotoa: 12349 Kalle 12.990\n91928 Ville 12009.005\n12001 Liisa 3409.250\n99999 Erkki 0.000<EOF> #include<stdio.h> void lisaatileja( void ); int main(void){ } lisaatileja(); return 0; 487

void lisaatileja ( void ) { int tilinro; char nimi[40]; double saldo; FILE *ptr; if ( ( ptr = fopen ("roskapankki.dat", "a" ) ) == NULL ) printf("\ntiedoston avaaminen epäonnistui\n"); else { do { printf("\nanna tilinumero, nimi, saldo. \n"); printf("anna - 1 tilinumeroksi, kun haluat lopettaa.\n"); printf("\ntilinumero?"); scanf("%d", &tilinro); if ( tilinro < 0 ) break; /* ulos silmukasta */ 488

printf("\nnimi? "); scanf("%s", nimi ); printf("\nsaldo? "); scanf("%lf", &saldo); fprintf(ptr, "%d %s %.2lf\n", tilinro, nimi, saldo); }while( 1 ); /* näennäisesti ikuinen silmukka */ fclose( ptr ); } } /* else */ 489

490

Vastaavasti kun halutaan lukea tekstitiedostosta ja tiedoston tarkka muoto tiedetään, voidaan käyttää funktiota fscanf 491

#include<stdio.h> int main(void){ FILE * ptr; int tilinro; double saldo; char nimi[40]; if (( ptr = fopen ("roskapankki.dat", "r" )) == NULL ) printf("\ntiedoston avaaminen avaaminen epäonnistui"); else { printf("%-12s%-13s%s\n","tilinumero", "Nimi","Saldo"); fscanf(ptr, "%d%s%lf", &tilinro, nimi, &saldo); 492

while(!feof( ptr)) { printf("%-12d%-13s%9.2lf\n", tilinro, nimi, saldo); fscanf(ptr, "%d%s%lf", &tilinro, nimi, &saldo); } fclose ( ptr ); } /* else */ return 0; } 493

494

Binääritiedostot Tekstitiedostoja lukiessa ohjelma muuttaa tietovirran merkit tietokoneen sisäiseen binääriesitykseen ja vastaavasti kirjoitettaessa toisinpäin. Usein ohjelmat tuottavat tiedostoja, jotka annetaan suoraan syöttötietona jollekin toiselle ohjelmalle eikä tiedoston sisältöä ole tarkoitus näyttää ihmiselle. Binääritiedostossa tieto talletetaan nimensä mukaisesti binäärisessä eli koneen ymmärtämässä muodossa. 495

Esimerkiksi luvun 593 tallettaminen käyttää 4 tavua (32 bittiä ), luku talletetaan binäärilukuna: 0000 0000 0000 0000 0000 0010 0101 0001 2 Vältetään turha muunnos kun käsittely tapahtuu koko ajan binäärisenä. Seuraava ohjelmakoodi luo binääritiedoston "nums.bin", joka sisältää parilliset kokonaisluvut 2-500 496

#include<stdio.h> int main(void){ FILE *binfile; int i; binfile = fopen ("nums.bin", "wb"); if(null!= binfile){ for ( i = 2; i <=500; i += 2) fwrite(&i, sizeof(int), 1, binfile); } fclose (binfile); } return 0; 497

Ero tekstitiedoston käsittelyyn fwrite-kirjastofunktio Funktiolla fwrite on neljä parametria 1. ensimmäisen kirjoitettavan tietoalkion osoite ( & ) 2. tietoalkion koko ( sizeof ) 3. yhdellä kertaa kirjoitettavien tietoalkioiden lukumäärä ( 1 ) 4. tiedoston osoite, jonne tiedot kirjoitetaan (binfile) 498

Jos taulukko score on 10 kokonaisluvun taulukko, kirjoittaisi seuraava lause koko taulukon binfile -osoittimen osoittamaan tiedostoon. fwrite( score, sizeof(int), 10, binfile ); 499

Lukemiseen vastaavasti funktio fread, jolla on neljä parametria 1. muuttujan osoite, jonne luettu tieto talletetaan ( & ) 2. luettavan tietoalkion koko (sizeof) 3. yhdellä kertaa luettavien tietoalkioiden maksimi lukumäärä 4. tiedoston osoite, josta tiedot luetaan fread ja fwrite palauttavat luettujen ja vastaavasti kirjoitettujen tietoalkioiden lukumäärän. 500

Tiedostotyyppejä ei kannata sekoittaa binäärit luetaan ja kirjoitetaan funktioilla fread ja fwrite tekstitiedostot luetaan ja kirjoitetaan funktioilla fscanf, fprintf sekä fgetc ja fputc 501

Suorasaantitiedostot Tiedostojen käsittelyssä suorasaanti mahdollistaa tietueen poimimisen mistä tahansa kohtaa tiedostoa. Suorasaanti perustuu tiedon fyysiseen sijaintikohtaan tiedostossa. Jos tiedostoon sijoitetaan peräkkäin neljä 20 tavun mittaista tietuetta, sijoittuvat ne seuraavasti 0 20 40 60 1. tietue 2. tietue 3. tietue 4. tietue 502

Käsittelyssä olennaista tiedosto-osoitin, joka näyttää kulloisenkin tiedoston fyysisen käsittelykohdan osoittimen siirtoon funktiot fseek ja rewind Suorasaantia käytetään yleensä binääritiedostojen yhteydessä, koska ei tarvitse tehdä muunnoksia. 503

Seuraavassa ohjelmassa tehdään suorasaantitiedosto tilikirjanpitoa varten. Oletetaan että kirjanpitoon riittää sadan tietueen tiedosto, jossa jokainen tietue koostuu kentistä int tilinro char sukunimi[15] char etunimi[15] double saldo #include <stdio.h> typedef struct asiakas_s { int tilinro; char sukunimi[15]; char etunimi[15]; double saldo; } Asiakas_t; 504

int main (void) { Asiakas_t tyhja = {0, "", "", 0.0 }; FILE * tiedosto; if (( tiedosto = fopen ("saldot.dat", "w")) == NULL ) printf("\ntiedoston avaaminen epäonnistui"); else { fwrite (&tyhja, sizeof(asiakas_t), 100, tiedosto); } fclose(tiedosto); return (0); } 505

Edellinen ohjelma loi suorasaantitiedoston "saldot.dat" ( oletushakemistoon ) ja alusti siihen sata tyhjää tietuetta, joita voidaan käyttää asiakastietueina. Seuraavana esiteltävä funktio lisää em. tiedostoon halutulle tilinumerolle ( = tietuenumero ) uudet asiakastiedot. Kirjoituksessa on löydettävä annettua tietueen numeroa vastaava paikka tiedostosta, jonne tiedot talletetaan. Paikka saadaan kaavalla ( tietueen järjestysnumero - 1 ) * tietueen koko Funktiota fseek käyttämällä voidaan käsittelykohta asettaa 506

kolmannelle tietueelle tyyppiä Asiakas_t tietovirtaan tiedosto fseek ( tiedosto, ( 3-1 ) * sizeof( Asiakas_t ), SEEK_SET ); Olennaista on huomata, että tiedoston osoitin tarkoittaa eri asiaan kuin tiedosto-osoitin. tiedoston osoitin näyttää käsiteltävän tiedoston tiedosto-osoitin näyttää käsittelykohdan tiedoston sisällä Funktiolla fseek asetetaan käsittelykohta, joka siirtyy yhdellä (Huom. osoitinaritmetiikka!) eteenpäin jokaisen fread -operaation 507

seurauksena. Funktion fseek kolmas parametri kertoo alkupisteen, josta siirtymisen laskenta alkaa. Vakion nimi Arvo Alkupiste SEEK_SET 0 Tiedoston alku SEEK_CUR 1 Nykyinen sijainti SEEK_END 2 Tiedoston loppu 508

#include <stdio.h> typedef struct asiakas_s { int tilinro; char sukunimi[15]; char etunimi[15]; double saldo; } Asiakas_t; void uusi ( FILE * tiedosto); void LueRoskat(void); int main (void) { int i; FILE * tiedosto; 509

if (( tiedosto = fopen ("saldot.dat", "r+")) == NULL ) printf("\ntiedoston avaaminen epäonnistui"); else { for(i=0; i<4;i ++) uusi( tiedosto ); //4 asiakasta talteen } fclose( tiedosto ); } return 0; 510

void uusi( FILE *tiedosto ) { Asiakas_t asiakas; int tili; printf("\nanna tilinumero ( 1-100): "); scanf("%d", &tili); lueroskat(); fseek(tiedosto,( tili - 1 ) * sizeof( Asiakas_t), SEEK_SET ); fread( &asiakas, sizeof( Asiakas_t), 1, tiedosto); 511

if( asiakas.tilinro!= 0 ) printf("\ntilinumero %d on jo käytössä!\n",asiakas.tilinro); else { printf("\nanna sukunimi, etunimi, saldo >\n"); scanf("%s%s%lf", asiakas.sukunimi, asiakas.etunimi, &asiakas.saldo); lueroskat(); asiakas.tilinro = tili; } fseek(tiedosto,(asiakas.tilinro-1)*sizeof(asiakas_t), SEEK_SET ); fwrite(&asiakas, sizeof(asiakas_t), 1, tiedosto); } void LueRoskat(void){ while(fgetc(stdin)!='\n'); } 512

Funktio lukee asiakastietoja binääritiedostosta ja kirjoittaa tiedot tekstimuodossa toiseen tiedostoon. Funktiolla rewind siirretään käsittelykohta tiedoston alkuun. 513

void teksti ( FILE *luku) { FILE *kirjoitus; Asiakas_t asiakas; } if( (kirjoitus = fopen ("saldot.dat", "w")) == NULL) printf("\ntiedostoa ei voitu avata\n"); else{ rewind( luku ); fprintf(kirjoitus,"%-6s%-16s%-16s%-10s\n","tili", "Sukunimi","Etunimi","Saldo"); fread (&asiakas, sizeof( Asiakas_t), 1, luku ); while(!feof( luku ) ) { if( asiakas.tilinro!= 0 ) fprintf( kirjoitus, "%-6d%-16s%-16s%10.2lf\n", asiakas.tilinro, asiakas.sukunimi, asiakas.etunimi, asiakas.saldo); fread (&asiakas, sizeof( Asiakas_t), 1, luku ); } } 514

Funktiolla ftell saadaan selville tiedosto-osoittimen senhetkinen arvo, tavuina tiedoston alusta. Tämän avulla voidaan laskea esim. montako asiakastietuetta tiedostossa on. #include <stdio.h> typedef struct asiakas_s { int tilinro; char sukunimi[15]; char etunimi[15]; double saldo; } Asiakas_t; 515

int main(void){ FILE * tiedosto; int kokotavuina; int tietueidenlukumaara; tiedosto = fopen("saldot.dat", "r"); if( NULL!= tiedosto ){ fseek( tiedosto, 0, SEEK_END ); /* tiedoston loppuun */ kokotavuina = ftell( tiedosto ); tietueidenlukumaara = kokotavuina / sizeof( Asiakas_t ); } printf("\ntiedosto \"saldot.dat\" sisältää %d\n tietuetta\n",tietueidenlukumaara ); fclose( tiedosto ); } return 0; 516

517

Taulukot ja tiedostot #include <stdio.h> #include <stdlib.h> #include <string.h> #define ITEMS 7 int main ( void ) { char filename [85] ="taulukko.dat"; int count; FILE *fileptr; int data[items] = {8, 57, 5, 309, 33, 87, 55 }; int data2[items]={0}; 518

if((fileptr = fopen ( filename, "w"))!= NULL){ printf("\nkirjoitan tietoalkioita tiedostoon %s...\n", filename); fwrite ( data, sizeof(data), 1, fileptr ); fclose ( fileptr ); if((fileptr = fopen ( filename, "r"))!= NULL) { printf ("\nluetaan tietoalkioita tiedostosta %s...\n", filename ); fread( &data2, sizeof(data), 1, fileptr ); fclose(fileptr); } printf("\ntaulukon tietoalkiot ovat:\n\n"); for ( count = 0; count < ITEMS; count++) { printf("data2[%d] arvo on %d\n", count, data2[count]); } } } return ( 0 ); 519

520