Anders Sjögren Filer - långtidslagring
Anders Sjögren Filtyper i DOS talet ett ( intx=1; ) lagrat i en –textfil, (en sekvens av tecken ( bytes )) enligt ASCII eller –binärfil, kopia av primärminnesinnehållet många system har endast en filtyp ( UNIX)
Anders Sjögren Textfiler Talet int x=1; ( typiskt 4 byte ) konverteras till ASCII-koden ( 1 byte: = ) för motsvarande symbol (tecknet ’1’) och vice versa. Primärminne ( int = 4bytes ) minst signifikant byte eller mest signifikanta byte kan ligga först (endianess) Sekundärminne- fil (ASCII = 1 byte) Konvertering till och från text Text= "ASCII"
Anders Sjögren Textfiler fördelar –data går ofta att hämta in i andra program som t ex ordbehandling och kalkylprogram –följer en standard - ASCII ( portabelt ) nackdelar –data kan inte lagras direkt utan måste konverteras till och från "text" –t ex strukturer, struct, är besvärligt att konvertera till "text” (vårt exempel med komplexa tal är inte speciellt besvärligt)
Anders Sjögren Textfiler - exempel ett program som läser heltal från tangentbordet och skriver heltalen som "text" till en textfil Om tangentbordet ses som en fil så genereras filslut från tangentbordet med CTRL-z ( i DOS )
Anders Sjögren Textfiler - exempel internt hanteras en fil som en pekare till typen FILE den interna pekaren knyts till en fysisk fil, filen öppnas för skrivning ( write), en ny fil skapas filen stängs #include int main(void) { FILE * textFil; intheltal; textFil = fopen("c:\\ett.txt", "w"); while ( !feof( stdin )){ fscanf(stdin,"%d",&heltal); fprintf( textFil,"%d ", heltal); } fclose(textFil); return 0 ; } Varför det är ett blank- tecken instoppat här återkommer vi till längre fram nästa bild
Anders Sjögren Textfiler - exempel konvertering från "text" till heltal konvertering från heltal till "text" #include int main(void) { FILE*textFil; intheltal; textFil = fopen("c:\\ett.txt", "w"); while ( !feof( stdin )){ fscanf(stdin,"%d",&heltal); fprintf( textFil,"%d ", heltal); } fclose(textFil); return 0 ; }
Anders Sjögren Ooops!
Anders Sjögren Textfiler - exempel onödigt att göra konvertering till heltal ( fscanf(stdin,"%d",&heltal); ) i detta fall, programmet "räknar" ju inte med dem! läs och skriv som tecken direkt, sparar bytes....
Anders Sjögren Textfiler - exempel #include int main(void) { FILE*textFil; chartecken; textFil = fopen("c:\\ett.txt", "w"); while (!feof( stdin )){ fscanf(stdin, "%c",&tecken); fprintf( textFil,"%c", tecken); } fclose(textFil); return 0 ; } Ger extra tecken i filen! feof() före fscanf().
Anders Sjögren Textfiler - exempel #include int main(void) { FILE*textFil; chartecken; textFil = fopen("c:\\ett.txt", "w"); while (fscanf(stdin, "%c",&tecken), !feof( stdin )){ fprintf( textFil,"%c", tecken); } fclose(textFil); return 0 ; } Denna ordning, fscanf() före feof(),är till för att undvika ”extra” tecken i filen. Filslut ctrl-z ställer till problem.
Anders Sjögren Fungerar!
Anders Sjögren Textfiler - exempel eller
Anders Sjögren Textfiler - exempel #include int main(void) { FILE*textFil; chartecken; textFil = fopen("c:\\ett.txt", "w"); while (tecken = fgetc(stdin),!feof( stdin )){ fputc( tecken,textFil); } fclose(textFil); return 0 ; } Eller så använder man funktionerna fgetc() och fputc()
Anders Sjögren Fungerar!
Anders Sjögren Textfiler - exempel tvärtom, läs från fil och skriv till bildskärm.....
Anders Sjögren #include int main(void) { FILE*textFil; intheltal; textFil = fopen("c:\\ett.txt", "r"); while ( !feof( textFil )){ fscanf(textFil, "%d",&heltal); fprintf( stdout,"%d", heltal); } fclose(textFil); return 0 ; } Textfiler - exempel öppnar befintlig fil för läsning (read)
Anders Sjögren Först, preparera filen ett.txt
Anders Sjögren Textfiler - exempel går det att både skriva och läsa en fil i samma program? ja det går bra med ett litet ”+” tillfogat textFil = fopen("c:\\ett.txt", "w+");
Anders Sjögren Textfiler - exempel forts, läsa och skriva från fil OK. Men det är något annat fel? #include int main(void) { FILE*textFil; intheltal; textFil = fopen("c:\\ett.txt", "w+"); while ( !feof( stdin )){ fscanf(stdin,"%d",&heltal); fprintf( textFil,"%d", heltal); } rewind(textFil); while ( !feof( textFil )){ fscanf( textFil,"%d",&heltal); fprintf( stdout,"%d", heltal); } fclose(textFil); return 0 ; } rewind(textFil); while ( !feof( textFil )){ fscanf( textFil,"%d",&heltal); fprintf( stdout,"%d", heltal); } fclose(textFil); return 0 ; } Nja,testa det här! Vad är felet? Prova först med två små tal och sedan med många tal.
Anders Sjögren Textfiler - exempel filbuffert ( tangentbordsbuffert ) scanf() läser i detta fall förbi tecken tills den hittar något, och så länge, som det går att konvertera till heltal i en läsning fscanf( textFil,"%d",&heltal) detta blir ett för stort tal! detta är OK!
Anders Sjögren Textfiler - exempel forts #include int main(void) { FILE*textFil; intheltal; textFil = fopen("c:\\ett.txt", "w+"); while ( !feof( stdin )){ fscanf(stdin,"%d",&heltal); fprintf( textFil,"%d ", heltal); } rewind(textFil); while ( !feof( textFil )){ fscanf( textFil,"%d",&heltal); fprintf( stdout,"%d", heltal); } fclose(textFil); return 0 ; } rewind(textFil); while ( !feof( textFil )){ fscanf( textFil,"%d",&heltal); fprintf( stdout,"%d", heltal); } fclose(textFil); return 0 ; } OK,men testa! Dubbla tecken? Lägger till ett blanktecken som separationstecken.
Anders Sjögren Textfiler - exempel forts #include int main(void) { FILE*textFil; intheltal; textFil = fopen("c:\\ett.txt", "w+"); while (!feof( stdin )){ fscanf(stdin,"%d",&heltal); fprintf( textFil,"%d ", heltal); } rewind(textFil); while (fscanf( textFil,"%d",&heltal), !feof( textFil )){ fprintf( stdout,"%d", heltal); } fclose(textFil); return 0 ; } rewind(textFil); while (fscanf( textFil,"%d",&heltal), !feof( textFil )){ fprintf( stdout,"%d", heltal); } fclose(textFil); return 0 ; } Ser bra ut, testa! För att läsa undan det sista blank- tecknet som finns inlagt i filen.
Anders Sjögren Fungerar!
Anders Sjögren Textfiler "w" write "r"read "a"append "w+"öppnar en ny fil för ”write” samt ”read” "r+"öppnar befintlig fil för ”read” samt ”write” "a+"öppnar fil för ”append” samt ”read”
Anders Sjögren Import till standardapplikationer Om ditt C-program skriver en HTML-fil så kan Du se filen med din Web-Browser!
Anders Sjögren /* website.c -- Makes HTML homepage for you */ #include #include #define SIZE 40 #define SERVER int main(int argc, char *argv[]) { char name[SIZE], adress[SIZE], tel[SIZE], zip[SIZE], user[SIZE]; FILE *out; /* Get user input */ printf("This program will help you with your homepage!\n"); printf("Type your full name.\n"); gets(name); printf("Type your adress.\n"); gets(adress); printf("Type your Zipcode and your State.\n"); gets(zip); printf("Type your telephone number.\n"); gets(tel); printf("Type your username (it's the first part of your mailadress).\n"); gets(user);
Anders Sjögren /* Make HTML-page */ out = fopen("hemsida.htm", "wt"); fprintf(out, " \n"); fprintf(out, " %s \n", name); fprintf(out, " \n"); fprintf(out, " \n"); fprintf(out, " Namn: %s \n", name); fprintf(out, " \n"); fprintf(out, " Adress: %s %s \n", adress, zip); fprintf(out, " \n"); fprintf(out, " Telefon: %s \n", tel); fprintf(out, " %s%s ", user, SERVER, user, SERVER); fprintf(out, " \n \n "); fclose(out); /* All done */ printf("\nThe webfile is now redy, and it's called \"hemsida.htm\".\n"); printf("Take a look at it with your web browser!"); system("PAUSE"); return 0; }
Anders Sjögren Utskrifter från våra C- program kan bli mycket "fräschare", om programmet skriver en HTML-fil som visas med datorns web-browser.
Anders Sjögren Textfil till Matlab /* sinc.c -- the (sin(x))/x function */ #include #include #define FILENAME "sinc.txt" double sinc(double); int main(int argc, char *argv[]) { double x, y; FILE *out; /* Get user input */ printf("This program will calculate sinc(x),"); printf(" and write x and sinc(x) to a file.\n"); /* Print function to file */ out = fopen(FILENAME, "wt"); for( x = -50; x < 50; x += 0.1) { y = sinc(x); fprintf(out, "%f\t%f\n", x, y); } fclose(out); printf("\nThe file is now redy, and it's called \"%s\".\n", FILENAME); printf("Load it into Matlab for a closer look!"); system("PAUSE"); return 0; } /* Definition of function sinc */ double sinc(double x) { double y; y = (sin(x))/x; return y; }
Anders Sjögren /* Definition of function sinc */ double sinc(double x) { double y; y = (sin(x))/x; return y; } För presentationen av siffervärden kan man med fördel dra nytta av proffessionella program som Matlab eller Excel.
Anders Sjögren Binärfiler Primärminne ( bytes ) int x=1; (4 bytes) Sekundärminne - filer Konvertering till och från text Direkt Minnesdump!
Anders Sjögren Binärfiler lagra på disk utan konvertering till text fördelar –snabbt, mycket data kan lagras på en gång –strukturer kan lagras i sin helhet nackdelar –andra program kanske inte kan läsa data t ex kalkylprogram –dålig portabilitet
Anders Sjögren int main(void) { int*tempPekare; intn,i,j; printf("Ange antal temperaturer --> "); scanf("%d",&n); tempPekare = (int *) calloc(n,sizeof(int)); /* calloc allokerar ett sammanhängande block,*/ /* detta medför "array-möjlighet" */ for (i=0 ; i<n ; i++){ printf("Ge temperatur %d --> ",i);scanf("%d",tempPekare+i); } for (i=0 ; i<n ; i++) printf("\ntemp %d = %d",i, tempPekare[i]); LagraPaFil( tempPekare, n); free(tempPekare) ; return 0; Binärfiler - exempel Pekarstegning resp index.
Anders Sjögren void LagraPaFil( int* tempPekare, int n ) { charfilnamn[25]; FILE*utFil; printf("\nAnge filens operativsystemnamn --> "); scanf("%s", filnamn ); utFil = fopen( filnamn, "wb"); fwrite( tempPekare, n*sizeof( *tempPekare ), 1, utFil); fclose( utFil ); return; } Binärfiler - exempel Skriver ( n*sizeof() ) bytes en gång från adress tempPekare till utFil. Returvärdet från fwrite() blir 0 eller 1 om skrivningen misslyckas eller ej.
Anders Sjögren Binärfiler - exempel eller......
Anders Sjögren void LagraPaFil( int* tempPekare, int n ) { charfilnamn[25]; FILE*utFil; printf("\nAnge filens operativsystemnamn --> "); scanf("%s", filnamn ); utFil = fopen( filnamn, "wb"); fwrite( tempPekare, sizeof( *tempPekare ), n, utFil); fclose( utFil ); return; } Binärfiler - exempel Skriver ( n*sizeof() ) bytes n gånger från adress tempPekare till utFil. Returvärdet från fwrite() blir 0 eller n,dvs antal lyckade skrivningar.
Anders Sjögren void LagraPaFil( int* tempPekare, int n ) { charfilnamn[25]; FILE*utFil; inttemp; printf("\nAnge filens operativsystemnamn --> "); scanf("%s", filnamn ); utFil = fopen( filnamn, "w+b"); fwrite( tempPekare, n*sizeof( *tempPekare ), 1, utFil); /* kontroll */ rewind( utFil ); while ( !feof(utFil) ){ fread( &temp, sizeof( int ), 1, utFil ); printf("\nTemperatur = %d", temp ) ; } fclose( utFil ); return; } Binärfiler - exempel tillägg på föregående program Nja, testa!
Anders Sjögren void LagraPaFil( int* tempPekare, int n ) { charfilnamn[25]; FILE*utFil; inttemp; printf("\nAnge filens operativsystemnamn --> "); scanf("%s", filnamn ); utFil = fopen( filnamn, "w+b"); fwrite( tempPekare, n*sizeof( *tempPekare ), 1, utFil); /* kontroll */ rewind( utFil ); while ( !feof(utFil) ){ fread( &temp, sizeof( int ), 1, utFil ); printf("\nTemperatur = %d", temp ) ; } fclose( utFil ); return; } Binärfiler - exempel tillägg på föregående program Inte bra, dubbelt på slutet
Anders Sjögren Binärfiler - exempel modifiering /* kontroll */ rewind( utFil ); while (fread( &temp, sizeof( int ), 1, utFil ) ) printf("\nTemperatur = %d", temp ) ; rewind( utFil ); while ( !feof(utFil) ){ fread( &temp, sizeof( int ), 1, utFil ); printf("\nTemperatur = %d", temp ) ; } rewind( utFil ); while ( !feof(utFil) ){ fread( &temp, sizeof( int ), 1, utFil ); printf("\nTemperatur = %d", temp ) ; } Testa!
Anders Sjögren void LagraPaFil( int* tempPekare, int n ) { char filnamn[25]; FILE *utFil; int temp, antal; char c; utFil = fopen( "temp.bin", "wb"); fwrite( tempPekare, n*sizeof( *tempPekare ), 1, utFil); /* kontroll */ fclose(utFil); utFil = fopen( "temp.bin", "rb"); printf("\n\nTemperatures from file:"); while (fread( &temp, sizeof( int ), 1, utFil )== 1 ) { printf("\nTemperatur = %d", temp ) ; } fclose( utFil ); return; } Tips! Variant. Läs så länge retur- värdet är det rätta … Kör vid labben …
Anders Sjögren Fungerar!
Anders Sjögren Binärfiler - exempel direktåtkomst, flytta aktuell position i filen /* kontroll */ rewind( utFil ); fseek(utFil, 1*sizeof( int ), SEEK_SET); fread( &temp, sizeof( int ), 1, utFil ) ; printf("\nTemperatur = %d", temp ) ; SEEK_xxx #defines #defines that set seek starting points Constant Value File Location SEEK_SET0Seeks from beginning of file SEEK_CUR1Seeks from current position SEEK_END2Seeks from end of file Declaration int fseek(FILE *stream, long offset, int whence);
Anders Sjögren Binärfiler ftell Returns the current file pointer Declaration long ftell(FILE *stream); Remarks ftell returns the current file pointer for stream. If the file is binary, the offset is measured in bytes from the beginning of the file
Anders Sjögren Byt plats på två poster i en fil Så här visar läroboken hur man kan byta plats på två poster i en binärfil. OBS! behövs ej för labuppgiften! /* byt plats på två poster i en fil */ #include struct vpost { long varunr; int antal; }; int main(void) { struct vpost vi, v2; FILE *lfil; lfil = fopen(”lagerfil”, ”rb+”); fseek(lfil, 58*sizeof(struct vpost), SEEK_SET); fread(&v1, sizeof(struct vpost), 1, lfil); fread(&v2, sizeof(struct vpost), 1, lfil); fseek(lfil, -2*sizeof(struct vpost), SEEK_CUR); fwrite(&v2, sizeof(struct vpost), 1, lfil); fwrite(&v1, sizeof(struct vpost), 1, lfil); fclose(lfil); } Sök post 58, läs 58 och 59, backa två steg, skriv 59 och 58.
Anders Sjögren "wb" write "rb"read "ab"append "wb+"öppnar en ny fil för ”write” samt ”read” "rb+"öppnar befintlig fil för ”read” samt ”write” "ab+"öppnar fil för ”append” samt ”read” Binärfiler
Anders Sjögren Slut