Programexempel från C-föreläsning 11, onsdag 10 januari 2007 ============================================================ Ny föreläsningsplanering ------------------------ Fö 11 (onsdag 10/1): filer med stdio (bl a binärfiler) -- T227 Fö 12 (fredag 12/1): felhantering, repetition, tentauppgifter, frågor -- Hörsal T Obs! Tentan på lördag går i Hörsal T kl 14-18. (Det stod en annan lokal tidigare, men den visade sig bli för liten.) reellatal.txt ------------- 4.92927 8.52385 6.1061 5.49319 3.16384 6.47934 0.405324 3.10623 7.66471 4.43504 0.0 filmedel.c ---------- #include #include int main() { FILE *tsin; double talet, summan; int antal; tsin = fopen("reellatal.txt", "rt"); if (tsin == NULL) { printf("Kunde inte öppna filen.\n"); return EXIT_FAILURE; } summan = 0.0; antal = 0; fscanf(tsin, "%lf", &talet); while (talet != 0.0) { summan += talet; ++antal; fscanf(tsin, "%lf", &talet); } fclose(tsin); printf("Medel = %f\n", summan / antal); return EXIT_SUCCESS; } /* main */ filmedel-2.c ------------ #include #include int main() { FILE *tsin; double talet, summan; int antal; if ((tsin = fopen("reellatal.txt", "rt")) == NULL) { printf("Kunde inte öppna filen.\n"); return EXIT_FAILURE; } summan = 0.0; antal = 0; while (fscanf(tsin, "%lf", &talet) != EOF) { summan += talet; ++antal; } fclose(tsin); printf("Medel = %f\n", summan / antal); return EXIT_SUCCESS; } /* main */ medlemmar.txt ------------- 13 Olle Svensson 14 Svea Olofsson 17 Kajsa Karlsson bimbatron padrone fo-11 >>> make medlemmar Två körexempel -------------- Ange ett medlemsnr: 17 Medlemmens namn: Kajsa Karlsson Ange ett medlemsnr: 15 Medlemmen finns inte. medlemmar.c ----------- #include #include #include struct Medlem { int nr; char namn[40 + 1]; }; /* Returnerar en medlem med nummer 0 om filen är slut */ struct Medlem las_medlem(FILE* tsin) { struct Medlem m; if (fscanf(tsin, "%d", &m.nr) == EOF) { m.nr = 0; return m; } while (getc(tsin) != '\n') ; fgets(m.namn, sizeof m.namn, tsin); int sista = strlen(m.namn) - 1; if (m.namn[sista] == '\n') m.namn[sista] = '\0'; return m; } int main() { FILE *tsin; if ((tsin = fopen("medlemmar.txt", "r")) == NULL) { printf("Kunde inte öppna filen.\n"); return EXIT_FAILURE; } int sokt_nr; printf("Ange ett medlemsnr: "); scanf("%d", &sokt_nr); struct Medlem m; m = las_medlem(tsin); while (m.nr != 0 && m.nr != sokt_nr) { m = las_medlem(tsin); } if (m.nr == sokt_nr) printf("Medlemmens namn: %s\n", m.namn); else printf("Medlemmen finns inte.\n"); return EXIT_SUCCESS; } /* main */ medlemmar-2.c ------------- #include #include #include struct Medlem { int nr; char namn[40 + 1]; }; // Returnerar 1 om det gick att läsa, 0 annars int las_medlem(FILE* tsin, struct Medlem* mp) { if (fscanf(tsin, "%d", &mp->nr) == EOF) return 0; while (getc(tsin) != '\n') ; fgets(mp->namn, sizeof mp->namn, tsin); int sista = strlen(mp->namn) - 1; if (mp->namn[sista] == '\n') mp->namn[sista] = '\0'; return 1; } int main() { FILE *tsin; if ((tsin = fopen("medlemmar.txt", "r")) == NULL) { printf("Kunde inte öppna filen.\n"); return EXIT_FAILURE; } int sokt_nr; printf("Ange ett medlemsnr: "); scanf("%d", &sokt_nr); struct Medlem m; while (las_medlem(tsin, &m)) { if (m.nr == sokt_nr) { printf("Medlemmens namn: %s\n", m.namn); return EXIT_SUCCESS; } } printf("Medlemmen finns inte.\n"); return EXIT_SUCCESS; } /* main */ Binärfil, binärström -------------------- På en binärfil har man inte översatt data till text, utan kopierat bitmönstren som de ser ut i primärminnet till filen. För att skriva eller läsa en binärfil används en binärström, som inte gör någon konvertering. Funktioner: fread, fwrite Två sorters format: textformat och binärformat ---------------------------------------------- int tal = 130; Binärt: 0000 0000 0000 0000 0000 0000 1000 0010 (128) (2) (0) (0) (0) (130) (32-bitars heltal i big-endian-ordning, dvs MSB först) Som text: 0011 0001 0011 0011 0011 0000 (49 = '1') (51 = '3') (48 = '0') Annat binärt: 0100 0001 0000 0000 (2) (128) (130) (0) (16-bitars heltal i little-endian-ordning, dvs LSB först) binart.c -------- #include int main() { int tal = 130; printf("Nu är talet = %d\n", tal); FILE *bsut; bsut = fopen("tal.bin", "wb"); fwrite(&tal, sizeof(tal), 1, bsut); fclose(bsut); printf("Nu är talet = %d\n", tal); FILE *bsin; bsin = fopen("tal.bin", "rb"); fread(&tal, sizeof(tal), 1, bsut); fclose(bsin); printf("Nu är talet = %d\n", tal); return 0; } /* main */ medlemmar-binart.c ------------------ #include #include #include struct Medlem { int nr; char namn[40 + 1]; }; int main() { FILE *bsin; if ((bsin = fopen("medlemmar.bin", "rb")) == NULL) { printf("Kunde inte öppna filen.\n"); return EXIT_FAILURE; } int sokt_nr; printf("Ange ett medlemsnr: "); scanf("%d", &sokt_nr); struct Medlem m; while (fread(&m, sizeof m, 1, bsin) == 1) { if (m.nr == sokt_nr) { printf("Medlemmens namn: %s\n", m.namn); return EXIT_SUCCESS; } } printf("Medlemmen finns inte.\n"); return EXIT_SUCCESS; } /* main */ kopiera.c --------- #include #include #include struct Medlem { int nr; char namn[40 + 1]; }; // Returnerar 1 om det gick att läsa, 0 annars int las_medlem(FILE* tsin, struct Medlem* mp) { if (fscanf(tsin, "%d", &mp->nr) == EOF) return 0; while (getc(tsin) != '\n') ; fgets(mp->namn, sizeof mp->namn, tsin); int sista = strlen(mp->namn) - 1; if (mp->namn[sista] == '\n') mp->namn[sista] = '\0'; return 1; } int main() { FILE *tsin; if ((tsin = fopen("medlemmar.txt", "r")) == NULL) { printf("Kunde inte öppna filen 'medlemmar.txt'.\n"); return EXIT_FAILURE; } FILE *bsut; if ((bsut = fopen("medlemmar.bin", "wb")) == NULL) { printf("Kunde inte öppna filen 'medlemmar.bin'.\n"); return EXIT_FAILURE; } struct Medlem m; while (las_medlem(tsin, &m)) fwrite(&m, sizeof m, 1, bsut); return EXIT_SUCCESS; } /* main */ Filer ----- -rw-r--r-- 1 padrone padrone 7862 Jan 9 16:58 anteckningar.txt -rw-rw-r-- 1 padrone padrone 419 Jan 9 16:19 binart.c -rw-rw-r-- 1 padrone padrone 453 Jan 8 17:01 filmedel-2.c -rw-rw-r-- 1 padrone padrone 502 Jan 8 16:56 filmedel.c -rw-rw-r-- 1 padrone padrone 906 Jan 9 16:25 kopiera.c -rw-rw-r-- 1 padrone padrone 104 Jan 8 14:55 Makefile -rw-rw-r-- 1 padrone padrone 930 Jan 9 16:09 medlemmar-2.c -rw-rw-r-- 1 padrone padrone 144 Jan 9 16:27 medlemmar.bin -rw-rw-r-- 1 padrone padrone 603 Jan 9 16:27 medlemmar-binart.c -rw-rw-r-- 1 padrone padrone 987 Jan 9 16:04 medlemmar.c -rw-rw-r-- 1 padrone padrone 52 Jan 9 15:52 medlemmar.txt -rw-rw-r-- 1 padrone padrone 802 Jan 8 16:52 reellatal.txt -rw-rw-r-- 1 padrone padrone 4 Jan 9 16:20 tal.bin -rw-rw-r-- 1 padrone padrone 3 Jan 8 16:45 tal.txt