[ Pobierz całość w formacie PDF ]

void macierz(tab x)
{
vprintf(" %%\n"
"%%5d%5d%5d %\n"
"%%5d%5d%5d %\n"
"%%5d%5d%5d %\n"
"%%\n",(va_list)x);
}
tab x={{1,2,192},{32,63,1092},{29,0,0}};
void main()
{
macierz(x);
}
Funkcja macierz wypisuje tablicę int[3][3] w eleganckiej postaci:
%%
% 1 2 192 %
% 32 63 1092 %
% 29 0 0 %
%%
Funkcji vprintf "wydaje się", że otrzymuje wskazanie do ciągu argumentów na
stosie. W rzeczywistości przekazujemy jej dwuwymiarową tablicę typu int pod-
daną wcześniej konwersji do typu va_list. Sztuczka udaje się dzięki temu, że tabli-
ca liczb całkowitych jest w pamięci reprezentowana tak samo jak odpowiednia
ilość argumentów typu int na stosie.
2.5. Funkcja cprintf
Deklaracja:
int cprintf(const char *format, ... );
Wiele kompilatorów oferuje rozszerzenia standardowych funkcji wyjściowych
zdefiniowanych przez ANSI. Do takich rozszerzeń należy funkcja cprintf, będąca
funkcją wyjścia na konsolę. Przejmuje ona ogólną "filozofię" funkcji printf
i akceptuje takie same sekwencje sterujące.
Czym różni się funkcja cprintf od funkcji printf? Otóż funkcja printf wypro-
wadza informacje do standardowego wyjścia, nie zaś na ekran. Za to, że wyprowa-
dzone przy pomocy funkcji printf napisy pojawiają się na ekranie (jeżeli
standardowe wyjście jest związane z ekranem) odpowiedzialny jest system opera-
cyjny. System operacyjny ma także pewien wpływ na sposób wypisania danych na
44 Wgłąb języka C
ekranie. Na przykład w systemie MS-DOS inny wynik może dawać program uru-
chomiony na komputerze z zainstalowanym sterownikiem ANSI.SYS, a inny na
komputerze bez tego sterownika. Dzieje się tak dlatego, że pomiędzy wyjściem
funkcji printf a ekranem konsoli "leży" system operacyjny, który przekształca
strumień wysłany przez program do standardowego wyjścia na odpowiedni efekt
na ekranie.
Jak natomiast działa funkcja cprintf? Przede wszystkim należy pamiętać, że nie
należy ona do standardu ANSI C. W różnych kompilatorach może ona działać
w różny sposób (niektóre kompilatory mogą w ogóle nie zawierać jej implementa-
cji). Generalnie funkcja cprintf wyprowadza swoje argumenty na ekran. Wynika
stąd, że zwykle z funkcją cprintf wiążą się takie pojęcia jak atrybuty tekstu,
współrzędne na ekranie, czy rozmiar okna, do którego jest wyprowadzany tekst.
Drugą różnicą jest to, że funkcja cprintf może niektóre znaki, będące dla systemu
znakami sterującymi (np. tabulacja), wypisywać dosłownie, jako odpowiednie
znaki z rozszerzonego zestawu ASCII. Wynik działania funkcji cprintf powinien
się pojawiać zawsze na ekranie - także wtedy, gdy wyjście standardowe zostało
przekierowane do pliku.
Jak napisałem, w różnych kompilatorach różnie to wygląda. Firma Borland bar-
dzo konsekwentnie realizuje tę funkcję jako funkcję wyjścia na ekran. Funkcje
ustawiające atrybuty tekstu wpływają na kolor napisów wypisywanych przez
funkcję cprintf. Można zdefiniować rozmiar i położenie na ekranie okna, do któ-
rego funkcja cprintf będzie wyprowadzała napisy, zaś kody sterujące są
w większości wypisywane jako odpowiednie znaki (np. ESC jako !).
Inaczej jest w kompilatorach Microsoftu, w których funkcja cprintf właściwie
niewiele różni się od funkcji printf. Jeżeli wyjście programu zostanie przekiero-
wane do pliku, to wynik działania funkcji cprintf nie pojawi się na ekranie lecz
zostanie również skierowany do tego pliku. Ponadto funkcje ustawiające atrybuty
tekstu nie wpływają na kolor tekstu wypisywanego przez funkcję cprintf.
Różnice pomiędzy konsolą a standardowym wejściem i wyjściem (analogicznie
do stdout jest także zdefiniowany plik stdin) są jeszcze lepiej widoczne
w przypadku funkcji formatowanego wejścia: scanf (wejście z stdin) i cscanf (wej-
ście z konsoli). Funkcje te zostaną opisane w dalszej części tego rozdziału.
3.Funkcje formatowanego wejścia
3.1. Funkcja scanf
Deklaracja:
int scanf(const char *format, ... );
III Formatowane wejście/wyjście 45
Funkcja ta czyta dane ze standardowego wejścia i po odpowiednim przetworze-
niu przypisuje je zmiennym, do których wskazniki przekazywane są jako argu-
menty. Normalnie standardowe wejście jest związane z konsolą użytkownika.
System operacyjny umożliwia zwykle zastąpienie konsoli dowolnym plikiem.
Przy użyciu mechanizmu potoków, można spowodować także pobieranie danych
z wyjścia innego programu.
Funkcja scanf ma jeden obowiązkowy parametr: const char *format. Ar-
gument skojarzony z tym parametrem wskazuje na ciąg znaków informujący funk-
cję scanf, jak należy zinterpretować ciąg wejściowy. Kolejne argumenty są
wskaznikami do zmiennych, którym należy przypisać zinterpretowane dane ze
strumienia wejściowego. Funkcja analizuje kolejne znaki ciągu format. Jeżeli znak
nie należy do sekwencji sterującej (sekwencja sterująca, podobnie jak w przypadku
funkcji printf, rozpoczyna się znakiem %), to jest on porównywany z kolejnym
znakiem z wejścia. Jeżeli znaki są różne, to funkcja scanf kończy swoje działanie,
w przeciwnym wypadku cała procedura jest powtarzana dla następnego znaku
w ciągu format i następnego znaku na wejściu. W specjalny sposób traktowane są
w ciągu format białe znaki ('\n',' ','\r' oraz '\t'). Zinterpretowanie w nim nawet jed-
nego białego znaku powoduje pominięcie w strumieniu wejściowym całego ciągu
białych znaków. Jeżeli białemu znakowi lub ciągowi białych znaków w ciągu for-
mat nie odpowiada co najmniej taka sama liczba białych znaków w strumieniu
wejściowym, to funkcja scanf kończy swoje działanie. Białe znaki nie są rozróż-
niane, (wszystkie są traktowane jak odstępy), dlatego też wystąpienie w ciągu ste-
rującym format np. znaku '\n' może spowodować pominięcie w strumieniu
wejściowym ciągu spacji.
Sekwencja sterująca w funkcji scanf ma prostszą postać niż w przypadku funkcji
printf. Zaczyna się ona znakiem % (procent), po którym mogą występować
opcjonalnie znak * (omówiony dalej) i liczba określająca maksymalną szerokość
pola wejściowego. Sekwencja kończy się specyfikatorem, którym może być jedna
z wymienionych poniżej liter:
d ciąg znaków ze strumienia wejściowego, po pominięciu poprzedzających bia-
łych znaków, jest interpretowany jako liczba całkowita w zapisie dziesiętnym.
Początkiem pola wejściowego jest więc pierwszy czarny znak w strumieniu wej-
ściowym a końcem pierwszy znak nie będący cyfrą dziesiętną. Jeżeli bezpośred-
nio po znaku % w sekwencji sterującej występuje liczba, to określa ona
maksymalną szerokość pola wyjściowego w znakach.
Opracowanie tej sekwencji kończy się sukcesem (tzn. przypisaniem odczytanej
danej zmiennej wskazywanej przez odpowiedni argument i kontynuacją działa-
nia funkcji scanf), jeżeli została odczytana przynajmniej jedna cyfra dziesiętna. [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • qus.htw.pl