2. Biblioteka C.

    Moze na poczatek taka uwaga: w Turbo C mozna ustawic kursor gdzies
    gdzie nie ma nic znanego kompilatorowi, wcisnac Ctrl-F1, i wtedy
    zapyta, czy chce sie "keywords", czy "header files". To drugie
    zawiera informacje o calej bibliotece. Dlatego omowione tu beda
    dokladniej tylko niektore czesci - reszte mozna doczytac w helpie.

2.1. Standardowe wejscie/wyjscie.

    Definicje do standardowego wejscia/wyjscia sa zawarte w pliku
    stdio.h. Z nich byly juz omowione funkcje formatujace wyjscie
    [v][f|s]printf i deformatujace wejscie [v][f|s]scanf. Uzywaja
    one - poza [v]sprintf i [v]sscanf, ktore dzialaja na tablicach
    typu char - zmiennej typu FILE, przekazywanej przez wskaznik
    (typu FILE*; dostep jest tylko przez wskaznik) opisujacej
    otwarty plik. Na poczatku program ma zdefiniowane i otwarte:
      stdin  - standardowe wejscie danych,
      stdout - standardowe wyjscie danych,
      stderr - standardowe wyjscie do sygnalizacji bledow,
      stdprn - standardowe wyjscie do drukowania,
      stdaux - standardowe wejscie/wyjscie szeregowe.
    Jezeli ktores z nich nie jest potrzebne, mozna zamknac je na
    poczatku - to moze miec sens, jesli potrzeba otwierac wiele
    plikow, i moglaby zostac przekroczona maksymalna ich ilosc.

    Do otwierania plikow sluza funkcje (typ wyniku FILE*):
      fopen(char *nazwa, char *mod) - normalne otwieranie pliku, mod
        moze miec wartosci "r" - do czytania, "r+" - do czytania i/lub
        modyfikacji, "w" - do pisania, "w+" - do pisania z mozliwoscia
        pozniejszego czytania, "a" - do pisania na koncu pliku, "a+" -
        z mozliwoscia czytania, mozna na koncu mod dodac b, zeby plik
        byl binarny, albo t zeby byl tekstowy;
      freopen(char *nazwa, char *mod, FILE *oldfile) - ta forma zamyka
        oldfile, i otwiera nowy plik, uzywajac tego samej zmiennej,
        skutek jest taki ze dalsze odwolania uzywajace niezmienionego
        wskaznika czytaja badz pisza nowy plik;
      fdopen(int uchwyt, char *mod) - otwiera plik do uchwytu - taki
        uchwyt opisuje otwarty plik na nizszym poziomie, i musi miec
        dostep zgodny z podamym modem, otrzymuje sie go zwykle przez
        funkcje z systemowego wejscia/wyjscia (opisane w io.h).
      tmpfile(void) - otwiera plik tymczasowy, do skasowania przy
        zamykaniu, zawsze binarny (mod="w+b");
    a do zamykania: fclose(FILE *file) i fcloseall(void) - ta druga
    zamyka wszystkie otwarte pliki opisane strukturami FILE. Uchwyt
    dla pliku mozna otrzymac z funkcji: int fileno(FILE *file).

    Opisane ponizej operacje zwykle uzywaja bufora (jest to bufor
    przypisany do pliku, nie mylic z buforem do ktorego czyta sie
    dane). Jego dlugosc jest zwykle 512 bajtow (stala BUFSIZ), mozna
    zazadac uzywania podanej tablicy jako bufora funkcja
      void setbuf(FILE *file, char *buf)
    jesli jako buf przekaze sie NULL operacje beda niebuforowane,
    mozna tez ustawic wiekszy bufor funkcja
      int setvbuf(FILE *file, char *buf, int rozm_elem, int ile_elem)
        (wynik niezerowy sygnalizuje blad).

    Nieformatowane operacje wejscia:
      int [f]getc(FILE *file) - czyta znak z pliku;
      int [f]getchar(void) - czyta znak z stdin
        (dla obu powyzej wersja z f wola funkcje, bez f makro);
      int getw(FILE *file) - czyta 2 znaki z file;
      char *gets(char *bufor) - czyta linie z stdin do bufora, konczy
        na \n (tego juz nie), bez limitu dlugosci, wynik=bufor (jesli
        jest blad, lub EOF, to wynik jest NULL = (char*)0);
      char *fgets(char *bufor, int dlugosc, FILE *file) - czyta linie
        z file do \n (z nim) lub dlugosc-1 znakow (1 znak na 0);
      int ungetc(int c,FILE *file) - cofa czytanie o 1 znak (wynik=
        przekazany znak) - nastepny getc zwroci ten znak;
      int fread(void *bufor, rozmiar_elem, ile_elementow, FILE *file)
        - wynik=ilosc elementow przeczytanych, -1 jezeli jest blad.

    Nieformatowane operacje wyjscia:
      int [f]putc(int c, FILE *file) - wypisuje znak, wynikiem jest
        wypisany znak (EOF w razie bledu);
      int [f]putchar(int c) - pisze znak na stdout;
        (dla obu powyzej wersja z f wola funkcje, bez f makro);
      int putw(int w, FILE *file) - wypisuje dwa znaki, wynik=w;
      puts(char *bufor) - wypisuje linie na stdout, wynik=ostatni
        wypisany znak, EOF w razie bledu, dodaje \n na koncu linii;
      fputs(char *bufor, FILE *file) - wypisuje linie na file, nie
        dodaje \n, wynik jak dla puts();
      int fwrite(void *bufor, rozmiar_elem, ile_elementow, FILE *file)
        - wynik=ilosc elementow zapisanych, -1 jezeli jest blad.

    Operacje ustawiania i odczytywania pozycji pliku:
      int rewind(FILE *file) - ustawianie na poczatek pliku
      int fgetpos(FILE *file, fpos_t *pos) - odczytywanie
      int fsetpos(FILE *file, fpos_t *pos) - ustawianie
      int fseek(FILE *file, long zmiana, int pozycja) - ustawianie,
        jako pozycja moze byc SEEK_SET (poczatek), SEEK_END (koniec),
        SEEK_CUR (aktualna), i zmiana dodaje sie do tej pozycji;
        (dla powyzszych wynik jest 0 jesli nie ma bledu)
      long ftell(FILE *file) - podaje aktualna pozycje, -1L jak blad.

    Inne operacje:
      int feof(FILE *file) - niezero jesli probowano przeczytac EOF;
      int ferror(FILE *file) - niezero jesli blad (EOF to nie blad);
      void clearerr(FILE *file) - kasuje stany blad i EOF;
      int fflush((FILE *file) - czysci bufor pliku (wypisuje na dysk);
      int flushall(void) - czysci bufory wszystkich plikow,
        zwraca ilosc otwartych plikow;
      void perror(char *napis) - pisze na stderr napis: opis bledu\n;
      int remove/unlink(char *nazwa_pliku) - kasuje ten plik
      int rename(char *s_nazwa,char *n_nazwa) - zmienia nazwe pliku;
      char *strerror(int errnum) - opis bledu numer errnum;
      char *tmpnam(char *bufor) - tworzy nazwe pliku tymczasowego,
        jako bufor mozna podac NULL - wtedy uzyje wlasnego bufora.

2.1. Wejscie/wyjscie "ekranowe" - wybrane funkcje.

    Definicje sa zawarte w conio.h, i jest to pakiet dostepny tylko
    w DOS-ie na PC. Mozna w nim ustawic parametry "okna" (fragmentu
    ekranu), i wtedy wszystkie operacje beda dotyczyc tylko tego
    okna (np. przewijanie tekstu, czyszczenie ekranu), i polozenie
    na ekranie bedzie liczone wzgledem okna. To okno definiuje sie
    funkcja window(x0,y0,x1,y1), ale zeby zaczelo dzialac trzeba
    jeszcze potem wejsc do niego przez gotoxy(x,y), wspolrzedne juz
    wedlug nowego okna. Aktualne wartosci wspolrzednych zwracaja
    funkcje wherex() i wherey(). Czyszczenie ekranu clrscr(), linii
    (do konca) clreol(). Mozna zapisac kawalek ekranu do pamieci
    funkcja gettext(x0,y0,x1,y1,char *buf), rozmiar buf ma byc
    2*(x1-x0+1)*(y1-y0+1) (2 bajty na znak ekranu), i potem wypisac
    go z powrotem na ekran funkcja puttext (takie same parametry).
    I sa delline() i insline() do kasowania i wstawianie linii.

    Przy pisaniu na ekran trzeba zwrocic uwage na to, ze \n nie jest
    zamieniany na \r\n - przesuwa kursor do nastepnej linii, ale nie
    na poczatek, a po prostu pionowo w dol. Do pisania sluza funkcje
    putch(c), cputs(char *s), cprintf(char *format...), dzialajace
    analogicznie jak putchar, puts, printf - tylko znacznie szybciej,
    zwlaszcza jezeli nie wyzeruje sie zmiennej directvideo.

    Za to z czytaniem sporo klopotow. Do czytania znaku sa getch()
    i getche() - ta druga funkcja daje echo, pierwsza nie. Czasem
    chce sie wiedziec, czy mozna czytac z klawiatury, czy tez bedzie
    sie czekac - kbhit() zwraca niezero jesli mozna cos przeczytac.
    Jesli wartoscia przeczytana jest zero, to zostal wcisniety jakis
    klawisz specjalny (np. F1-F12), albo z Alt, i trzeba przeczytac
    nastepny znak uzywajac getch() - wartosc podaje kod skanowania
    tego klawisza. Funkcji cscanf() i cgets() lepiej nie uzywac.
    Do czytania napisu bez echa jest getpass(char *prompt) - po to,
    zeby wczytywac haslo nie pokazujac go na ekranie. Mozna "cofnac"
    czytanie o 1 znak przez ungetch(c), tylko (char)c nie moze byc 0.

    Znaki na ekranie moga miec atrybuty (kolor znaku i tla), mozna to
    ustawiac funkcjami lowvideo(), normvideo(), highvideo() - jasnosc,
    lub textcolor(c), textbackground(c) - kolory tekstu i tla, kazdy
    z osobna - lub textattr(c) - oba razem. Do ustawiania pozycji na
    ekranie jest juz wspomniana gotoxy(x,y). Szczegolowe informacje
    o aktualnych ustawieniach mozna uzyskac przez gettextinfo(...).
    A z uzywaniem textmode(mod) lepiej zachowac ostroznosc.

2.3. Podstawowe operacje na napisach (i pamieci).

    Definicje sa zawarte w string.h. Do kopiowania sa funkcje
      char *str[n]cpy(char *dokad, char *skad [, int ilosc]);
    ilosc znakow podaje sie w wersji z n w nazwie; kopiowanie konczy
    sie na znaku \0 lub po osiagnieciu podanej ilosci - i wtedy nie
    dopisuje \0 na koncu; nie ma zabezpieczenia przed skopiowaniem do
    zbyt krotkiej tablicy wynikowej; jako wartosc zwraca adres dokad;
    jest tez stpcpy, ktory dziala tak samo, ale zwraca adres konca.

    Do porownywania sa: int str[n][i]cmp, takie same parametry (ilosc
    tylko jesli n w nazwie); i w nazwie powoduje ignorowanie roznicy
    miedzy malymi i duzymi literami; wartosc 0 oznacza "identyczne",
    <0 pierwszy mniejszy, >0 pierwszy wiekszy (jako signed char).

    Mozna dopisac do konca napisu przez str[n]cat - znow parametry
    takie same, ilosc podaje maksymalna dlugosc tego, co ma sie
    dopisac, nie calkowity rozmiar tego, co ma wyjsc.

    Dlugosc mozna otrzymac przez strlen(char *napis) - podaje gdzie
    jest to konczace zero; znalezc zadany znak w napisie mozna przez
      char *strchr(char *napis, int znak) - zwroci jego adres, lub
    NULL jesli tego znaku nie bedzie; podobny strrchr szuka od konca.
    Do szukania napisu jest char *strstr(char *w_czym, char czego).

    Mozna skopiowac przydzielajac na to pamiec - robi to funkcja
      char *strdup(char *napis) - tyle, ze po pierwsze trzeba ja
    zwracac jak kopia przestaje byc potrzebna, po drugie dostaje
    sie jej tylko tyle, ile zajmie kopia - nie mozna nic dopisac.

    Mozna zamienic wszystkie litery w napisie na male lub na duze -
    do tego sa strlwr(char *napis) i strupr, ich wynik=parametr.

    Sa jeszcze bardziej skomplikowane operacje: znajdowanie dlugosci
    kawalka zawierajacego wylacznie podane znaki, lub wylacznie znaki
    spoza podanych (strspn,strcspn), znajdowanie pierwszego znaku
    z podanego zestawu (strpbrk), i pare innych mniej uzytecznych.

    Oprocz zestawu "str" jest zestaw funkcji "mem", ktore roznia
    sie tym, ze nie uznaja \0 ani niczego innego za koniec, uzywaja
    wskaznikow void * (jest im wszystko jedno na co one pokazuja),
    i zawsze specyfikuja ilosc bajtow, poza tym sa analogiczne:
      memcpy (ma tez nazwe memmove), memchr, mem[i]cmp;
    memset(void *gdzie, int na_co, int ilosc) - zapisuje podana ilosc
    bajtow podana wartoscia (ma odpowiedniki str[n]set). Funkcje
    movmem i setmem roznia sie od memcpy i memset tylko kolejnoscia
    parametrow. Jest jeszcze memccpy, ktora kopiuje do podanego znaku,
    i jako wynik zwraca jego adres (NULL jak nie ma), i movedata,
    ktora ze wzgledu na sposob adresowania bedzie omowiona osobno.
    Caly ten zestaw ("mem") jest rowniez w mem.h.

2.4 O kilku innych pakietach.

    alloc.h    - wszystkie funkcje zwiazane z przydzielaniem pamieci
                 do zmiennych wskaznikowych i zwalnianiem jej;
    assert.h   - zawiera jedna funkcje: void assert(int test);
    bios.h     - funkcje odwolujace sie do BIOS-u PC;
    conio.h    - we/wy klawiatura/ekran (*);
    ctype.h    - zawiera definicje do klasyfikowania znakow (cyfra,
                 cyfra hex, litera dowolna/mala/duza, sterujacy,...)
                 i konwersji malych liter na duze lub duzych na male;
    dir.h      - wszystko co laczy sie ze struktura katalogow na dysku
                 i nazwami plikow (np. szukanie plikow w katalogu);
    dos.h      - operacje i definicje specyficzne dla DOS-u na PC;
    float.h    - funkcje do sterowania koprocesorem numerycznym;
    graphics.h - funkcje i definicje do modu graficznego na ekranie;
    io.h       - funkcje do operacji we/wy uzywajacych uchwytow;
    math.h     - funkcje matematyczne;
    mem.h      - operacje na pamieci (kopiowanie, porownywanie) (*);
    process.h  - wywolywanie i konczenie programow;
    setjmp.h   - pozwala zapisac stan programu i do niego wrocic,
                 mozna uzyc przy obsludze bledow, do multitaskingu;
    signal.h   - podlaczanie procedur pod sygnaly o bledzie,
                 i generowanie takich sygnalow;
    stdarg.h   - definicje do obslugi zmiennych list parametrow;
    stdio.h    - standardowe funkcje we/wy (*);
    stdlib.h   - rozne funkcje (wiele jest gdzie indziej);
    string.h   - operacje na tablicach znakow + mem.h (*);
    sys\stat.h - funkcje do informacji systemowych o otwartym pliku;
    time.h     - wszystko co laczy sie z czasem i data;
    (*) oznacza, ze pakiet zostal juz omowiony.
