310 likes | 427 Views
Počítače a programování 2. Přednáška 2 17.2.2014 Jiří Šebesta. T ÉMA. Souborový vstup a výstup Programování WAV Programování BMP. Souborový vstup a výstup (1/10). Binární vs. textový soubor.
E N D
Počítače a programování 2 Přednáška 2 17.2.2014 Jiří Šebesta
TÉMA Souborový vstup a výstup Programování WAV Programování BMP
Souborový vstup a výstup (1/10) Binární vs. textový soubor ANSI C používá tzv. bufferovaný přístup k souborům pomocí proudu (stream) nebo-li ukazatele na strukturu typu FILE (definice v knihovně stdio.h) V ANCI C není rozdíl mezi souborem a zařízením (portem) – přistupuje se stejně • Binární soubor • - překladač neprovádí žádnou úpravu čtených a zapisovaných dat • uspořádání dat v souboru je nezávislé a specifické pro dané využití
- přenositelnost binárních souborů mezi různými systémy může být omezena rozdílnou délkou základních typů v těchto různých systémech – nutno vždy vhodně ošetřit Souborový vstup a výstup (2/10) • Textový soubor • uspořádán po řádcích, každý zakončen znakem \n • v některých OS se před \n vkládá \r(úpravu zajišťují funkce ze standardní knihovny stdio.h. • lze zobrazit libovolným editorem
Otevření souboru: FILE *fopen(char *file_name, char *mode) - mode reprezentuje řetězec pro režim otevření souboru (viz BPC1E), pro binární soubory je doplněn do řetězce znak ‘b‘, např. “rb“ = otevření binárního souboru pro čtení “wb“ = otevření prázdného binárního souboru pro zápis “ab“ = otevření binárního souboru pro zápis na konec stávajícího souboru Souborový vstup a výstup (3/10) Rozšířené režimy: “r+“ = otevření existujícího souboru pro čtení a zápis, pokud soubor neexistuje vrací se NULL “w+“ = otevření nového prázdného souboru pro zápis i čtení, pokud soubor existuje, je původní obsah smazán “a+“ = otevření existujícího souboru pro zápis na konec a čtení kdekoli
Souhrnné vlastnosti režimů otevření souborů Souborový vstup a výstup (4/10)
Uzavření souboru: • int *fclose(FILE *fptr) • - v případě správného uzavření se vrací 0, v případě neúspěšného uzavření se vrací EOF • podle ANSI-C se při správném ukončení programu otevřené soubory automaticky uzavřou, v případě havárie programu však není jednoznačně definováno, co se s otevřeným souborem stane Souborový vstup a výstup (5/10) Formátované vstupy/výstupy: int fprintf(FILE *fptr, const char *form, …) = zápis řetězce form do souboru fptr, pokud je obsahem řetězce hodnota číselné proměnné, zapisuje se jeho vyjádření řetězcem int fscanf(FILE *fptr, const char *form, …) = čtení řetězce ze souboru fptr a uložení do řetězce form
Neformátované vstupy/výstupy: int fputc(int c, FILE *fptr) = zápis znaku c do souboru fptr int fgetc(FILE *fptr) = čtení znaku ze souboru fptr jako návratová hodnota Možno použít i makra (význam stejný, jen rychlejší, ale může být větší program): int putc(int c, FILE *fptr) int getc(FILE *fptr) Souborový vstup a výstup (6/10)
Příklad: Kopírování binárního souboru in.bin do out.bin po bytech Souborový vstup a výstup (7/10) #include <stdio.h> int main() { FILE *frptr, *fwptr; int ch; frptr = fopen("in.bin","rb"); fwptr = fopen("out.bin","wb"); while((ch=fgetc(frptr))!= EOF) fputc(ch, fwptr); fclose(frptr); fclose(fwptr); return0; } Příklad: Ex88.c
Čtení/zápis celého řádku najednou (jen pro textové soubory): char *fgets(char *str, int max, FILE *fptr) = přečte celý řádek v textovém souboru fptr a uloží jej jako řetězec do str a to do maximálního počtu znaku max,pokud je řádek v souboru delší než max, zbytek řádku může být přečten následujícím čtením, vrací ukazatel na řetězec str,v případě dočtení posledního řádku souboru vrací NULL,do řetězce jsou ukládány i znaky‘\n’. int fputs(char *str, FILE *fptr) = zápis řádku z řetězce str do souboru fptr Souborový vstup a výstup (8/10)
Příklad: Kopírování textového souboru in.txt do out.txt po řádcích Souborový vstup a výstup (9/10) #include <stdio.h> #define LEN_OF_ROW 10 int main() { FILE *frptr, *fwptr; char txt[LEN_OF_ROW]; frptr = fopen("in.txt","r"); fwptr = fopen("out.txt","w"); while(fgets(txt, LEN_OF_ROW, frptr)!=NULL) fputs(txt, fwptr); fclose(frptr); fclose(fwptr); return0; } Příklad: Ex89.c
Čtení/zápis celého bloku najednou (pro binární soubory): size_t fread(void *ptr, size_t size, size_t cnt, FILE *fptr) = přečte celý blok položek o velikosti size v souboru fptr o celkovém počtu cnt a uloží jej jako pole elementů do pole v paměti referen-covaného ukazatelem ptr, vrací se počet skutečně načtených položek size_t fwrite(const void *ptr, size_t size, size_t cnt, FILE *fptr) = uloží celý blok položek definovaných jako pole elementů v paměti referencovaného ukazatelem ptr o velikosti size do souboru fptr o celkovém počtu cnt, vrací se počet skutečně úspěšně uložených položek Souborový vstup a výstup (10/10)
Soubor typu WAV – bezkompresní audio Programování WAV (1/6) Struktura souboru WAV (podmnožina RIFF)
Příklad: Vygenerujte soubor typu WAV, který bude obsahovat jeden tón dané frekvence, amplitudy, doby trvání a jména cílového WAV souboru (argumenty při spouštění programu) Programování WAV (2/6) #include <stdio.h> #include <stdlib.h> #include <math.h> #define TPI 6.283 int fwrite_int(int val,char len, FILE *p) { char byte; while(len-->0) { byte = val &0xFF; fwrite(&byte, 1, 1, p); val >>=8; } return0; } Pomocná funkce pro zápis různě dlouhých dat hlavičky do WAV souboru jako little endian
int main(int argc, char*argv[]) { doubleph, deltaph, tdur, ampl, freq; intnumsa, srate; unsigned char sig; FILE *ptrf; if(argc ==5) { srate =8000;// fixed sample rate 8 kHz freq = atof(argv[1]);// tone freq - 1. argument in Hz ampl = atof(argv[2]);// tone amplitude - 2. argument tdur = atof(argv[3]);// tone duration - 3. argument in s numsa = tdur*srate;// overall number of samples ph =0;// initial phase 0 rad deltaph = TPI * freq /srate;// delta phase ptrf = fopen(argv[4],"wb"); fwrite("RIFF",4,1, ptrf);// chunk_id RIFF fwrite_int(36+ numsa,4, ptrf);// chunk_size fwrite("WAVE",4,1, ptrf);// spec. RIFF form for WAV fwrite("fmt",4,1, ptrf);// subchunk1id - format Programování WAV (3/6)
fwrite_int(16,4, ptrf);// subchunk1size 16 for PCM fwrite_int(1,2, ptrf);// audio_format, 1 = PCM fwrite_int(1,2, ptrf);// channels, 1=mono fwrite_int(srate,4, ptrf);// sample rate fwrite_int(srate *1*8/8,4, ptrf);// byte rate fwrite_int(1*8/8, 2, ptrf);// block align fwrite_int(8,2, ptrf);// bits per sample, 8 bits fwrite("data",4,1, ptrf);// subchunk2id - data fwrite_int(numsa *1*8/8,4, ptrf);// subchunk2 size while(numsa-->0) { sig =128*(ampl*sin(ph)+1); fwrite(&sig,1,1, ptrf); ph += deltaph; } fclose(ptrf); } else printf("Wrong number of arguments!!!!\n"); return0; } Programování WAV (4/6) Příklad: Ex90.c
Příklad: Vygenerujte soubor typu WAV, který bude měnit tón od zadané frekvence do zadané frekvence, s danou amplitudou, dobou trvání a jménem cílového WAV souboru (argumenty při spouštění programu) Programování WAV (5/6) Příklad: Ex91.c– bude zveřejněn 24.2.2014
Příklad – domácí úloha: Sestavte program, který vygeneruje soubor typu WAV, který bude obsahovat DTMF signální volbu podle zadaného kódu. Kód a cílový soubor jsou argumenty při spouštění programu. V programu proveďte rovněž korekci možných znaků DTMF kód, nepovolené znaky vylučte. Jeden dvojtón trvá 50 ms následuje mezera 50 ms. Programování WAV (6/6) Příklad: Ex92.c– bude zveřejněn 24.2.2014
Soubor typu BMP – pixelový RGB obrázek Programování BMP (1/12) Každý korektní soubor typu BMP obsahuje několik datových struktur definovaných WinAPI:
Hlavička souboru typu BMP, tj. datová struktura BITMAPFILEHEADER, má délku čtrnácti bytů a obsahuje údaje o typu, velikosti a celkovém uspořádání dat v souboru. Programování BMP (2/12)
Datová struktura BITMAPINFOHEADER obsahuje základní metainformace o rastrovém obraze. Mezi tyto informace patří především jeho rozměry, tj. výška a šířka, dále pak identifikace použité komprimační metody a specifikace formátu rastrových dat. Celková velikost této struktury je vždy rovna 40 bytů. Programování BMP (3/12)
RGBQUAD[] obsahuje pole definující barevnou paletu pro omezený počet barev (nemusí být definováno, pak plnobarevná paleta) Programování BMP (6/12) BITSobsahuje pole definující jednotlivé pixely, tak jak jdou za sebou, při kompresním RGB jsou to čísla jednotlivých barev, při nekompresním RGB obsahují úroveň složek R, G a B. V knihovně windovs.h je definována struktura pro jeden pixel: RGBTRIPLE s položkami pro jednotlivé barvy s rozsahem unsigned char (0x00 – 0xFF) rgbtRed, rgbtGreen, rgbtBlue
Příklad: Vygenerujte ze vstupního bezkompresního BMP obrázku, obrázek inverzní, obrázek stupňů šedi, obrázek jen s červenou složkou, jen se zelenou složkou, jen s modrou složkou Programování BMP (7/12) #include <windows.h> #include <stdio.h> int main() { BITMAPFILEHEADER bmp_fh;//structure for BMP file header BITMAPINFOHEADER bmp_ih; //structure for BMP info header RGBTRIPLE bmp_rgb; //structure for triplet of one pixel unsigned char Red, Gre, Blu, Av; FILE *fRGB,*fRED,*fGRE,*fBLU,*fINV,*fBAW; size_t padd; int i, j;
fRGB = fopen("RGB.bmp","rb");//old BMP fRED = fopen("RED.bmp","wb");//new BMP red fGRE = fopen("GREEN.bmp","wb");//new BMP green fBLU = fopen("BLUE.bmp","wb");//new BMP blue fINV = fopen("INVERT.bmp","wb");//new BMP inverted fBAW = fopen("BANDW.bmp","wb");//new BMP black&white //BITMAPFILEHEADER copy to new BMP files fread(&bmp_fh, sizeof(bmp_fh),1, fRGB);//old BMP fwrite(&bmp_fh, sizeof(bmp_fh),1, fRED); fwrite(&bmp_fh, sizeof(bmp_fh),1, fGRE); fwrite(&bmp_fh, sizeof(bmp_fh),1, fBLU); fwrite(&bmp_fh, sizeof(bmp_fh),1, fINV); fwrite(&bmp_fh, sizeof(bmp_fh),1, fBAW); Programování BMP (8/12)
//BITMAPFILEHEADER copy to new BPM files fread(&bmp_ih, sizeof(bmp_ih),1, fRGB);//old BMP fwrite(&bmp_ih, sizeof(bmp_ih),1, fRED); fwrite(&bmp_ih, sizeof(bmp_ih),1, fGRE); fwrite(&bmp_ih, sizeof(bmp_ih),1, fBLU); fwrite(&bmp_ih, sizeof(bmp_ih),1, fINV); fwrite(&bmp_ih, sizeof(bmp_ih),1, fBAW); padd = 0; if((bmp_ih.biWidth *3) %4)// padding test padd = 4-(bmp_ih.biWidth *3) %4; Programování BMP (9/12)
for(i =0; i < bmp_ih.biHeight; i++) { for(j =0; j < bmp_ih.biWidth; j++) { fread(&bmp_rgb, sizeof(bmp_rgb),1, fRGB); Red = bmp_rgb.rgbtRed; Gre = bmp_rgb.rgbtGreen; Blu = bmp_rgb.rgbtBlue; bmp_rgb.rgbtRed = Red; bmp_rgb.rgbtGreen =0x00; bmp_rgb.rgbtBlue =0x00; fwrite(&bmp_rgb, sizeof(bmp_rgb),1, fRED); bmp_rgb.rgbtRed =0x00; bmp_rgb.rgbtGreen = Gre; bmp_rgb.rgbtBlue =0x00; fwrite(&bmp_rgb, sizeof(bmp_rgb),1, fGRE); Programování BMP (10/12)
bmp_rgb.rgbtRed =0x00; bmp_rgb.rgbtGreen =0x00; bmp_rgb.rgbtBlue = Blu; fwrite(&bmp_rgb, sizeof(bmp_rgb),1, fBLU); bmp_rgb.rgbtRed =0xFF- Red; bmp_rgb.rgbtGreen =0xFF- Gre; bmp_rgb.rgbtBlue =0xFF- Blu; fwrite(&bmp_rgb, sizeof(bmp_rgb),1, fINV); Av =(Red + Gre + Blu)/3; bmp_rgb.rgbtRed = Av; bmp_rgb.rgbtGreen = Av; bmp_rgb.rgbtBlue = Av; fwrite(&bmp_rgb, sizeof(bmp_rgb),1, fBAW); } Programování BMP (11/12)
Programování BMP (12/12) if(padd !=0) { fread(&bmp_rgb, padd,1, fRGB); fwrite(&bmp_rgb, padd,1, fRED); fwrite(&bmp_rgb, padd,1, fGRE); fwrite(&bmp_rgb, padd,1, fBLU); fwrite(&bmp_rgb, padd,1, fINV); fwrite(&bmp_rgb, padd,1, fBAW); } } fclose(fRGB); fclose(fRED); fclose(fGRE); fclose(fBLU); fclose(fINV); fclose(fBAW); return0; } Příklad: Ex93.c
TÉMA NÁSLEDUJÍCÍHOTUTORIÁLU Úvod do objektově orientovaného programování a C++ DĚKUJI ZA POZORNOST