Jason. Cała informatyka w jednym miejscu!

Na dzisiejszy dzień malutka dawka nowej porcji wiedzy odnośnie języka C. Analizując co już napisałem a czego jeszcze nie, postanowiłem sięgnąć wstecz do dużo prostszych zagadnień i zająć się omawianiem modyfikatora funkcji "printf" i "scanf", który jest mało znany. Modyfikator to coś innego niż specyfikator. Oznacza on możliwość wywierania wpływu na formatowanie danych wyjściowych w miejsce wprowadzonego specyfikatora, który podlega zmianie na odpowiedni parametr. Dzisiaj poruszę wątek co nam daje modyfikator gwiazdki, choć w rzeczywistości to jest "asterysk" (ang. "asterisk"), który jest na tyle wyjątkowy, że oznacza on coś zupełnie innego zarówno dla jednej, jak i dla drugiej funkcji. Zweryfikujcie ponownie swoje twierdzenie czy rzeczywiście znacie już wszystkie modyfikatory.

MODYFIKATOR GWIAZDKI W DWÓCH ZNACZENIACH

DLA FUNKCJI "PRINTF"

Najpierw funkcja wyjściowa "printf". Użycie w łańcuchu formatującym znaku "asterysku" pozwala na ustawienie wartości liczbowej w danym specyfikatorze formatu w zależności od podanej zmiennej jako jednego z parametrów następnych. Zaprezentuję krótki fragment kodu źródłowego. Przypuśćmy, że dysponując tekstem chcemy ustawić własną szerokość przeznaczoną dla niego pola. Wpisując w taki sposób:

printf("[%s]", "Programowanie w C");

szerokość pola będzie automatycznie dostosowana do liczby znaków bez uwzględnienia znaku "terminatora" (ang. "null terminator") w postaci '\0'. Wprowadzając tak:

printf("[%30s]", "Programowanie w C");

szerokość zostanie dostosowana do 30 znaków, pod warunkiem że tekst posiada mniej znaków niż ustalona liczba. Dodając znak minusa po znaku procentu, tekst zostanie wyrównany do lewej strony. Idąc dalej mamy kolejną możliwość. Modyfikator w postaci gwiazdki:

printf("[%*s]", 100, "Programowanie w C");

Widzicie to? Potrzebny jest osobny parametr reprezentujący liczbę całkowitą! Uważając na to, możemy od tej pory wygodnie manipulować szerokością pobierając ją ze stałej, a jeszcze lepiej ze zmiennej na przykład wcześniej wprowadzanej z funkcji "scanf", o której jest więcej informacji w następnym akapicie. Stosując stałą, polecam umieścić sobie taką liczbę na zewnątrz jako stałą z dyrektywy albo z modyfikatorem "const". Na koniec, przykładowy kod źródłowy gotowy do skompilowania:

#include <stdio.h>

#define WIDTH 30

int main(void)
{
	printf("[%s]\n", "Programowanie w C");
	printf("[%30s]\n", "Programowanie w C");
	printf("[%*s]\n", WIDTH, "Programowanie w C");
	getchar();

	return 0;
}

DLA FUNKCJI "SCANF"

Teraz funkcja odczytująca dane z bufora: "scanf". Rozdzieliłem obie te funkcje z jednego istotnego powodu: ten sam modyfikator oznacza coś zupełnie innego w jednej i w drugiej funkcji! Tutaj odgrywa on ZUPEŁNIE INNĄ rolę. Użycie "asterysku" w miejsce "scanf" skutkuje zignorowaniem konkretnego "wykrytego" specyfikatora. Ma to na celu pominięcie pewnej kolumny danych istniejącej w jakiejś tabelce czy sformatowanym pliku zewnętrznym na kształt tabelki, gdybyśmy chcieli wprowadzać do nich własne dane. Niekoniecznie muszą być na początku, można taką gwiazdkę dać pomiędzy zwracając baczną uwagę na kolejne parametry czy są zgodne z następnymi specyfikatorami (albo niezdefiniowane zachowanie!). Oto parę przykładów:

int x;

scanf("%d", &x);

Nic specjalnego. Prośba o podanie liczby całkowitej i albo grzecznie ją wstawimy, albo nie i zastaniemy "śmieciową" wartość. A co powiecie na coś takiego, gdy modyfikator gwiazdki zostanie użyty?

int x;

scanf("%*d %d", &x);

Zastanawiacie się czemu jest jedna wartość po łańcuchu formatującym zamiast dwóch? Bo modyfikator odrzuca dany specyfikator! Ponieważ staje się on nieważny, nie ma potrzeby wstawiać kolejnego parametru zgodnego z podanym specyfikatorem. Zapamiętajcie jednak, że mimo wszystko i tak musimy w tej sytuacji podać dwie liczby całkowite, tylko że zostanie uwzględniona tylko ta druga. Nie szkodzi, i tak musimy podać dwie! Podając na przykład liczby 42 i 8, do zmiennej "wejdzie" tylko ósemka. Oto przykład do kompilacji:

#include <stdio.h>

int main(void)
{
	int x;
	
	printf("Podaj dwie liczby (zmiennoprzecinkowa i calkowita): ");
	scanf("%*f %d", &x);
	printf("Podana liczba to %d\n", x);
	getchar();
	getchar();

	return 0;
}

Podwójne wywołanie funkcji "getchar" nie jest przypadkowe. W chwili zatwierdzenia OBU wartości liczbowych klawiszem Enter, program automatycznie przechwytuje znak nowej linii ('\n'), przez co pierwszy "getchar" jest już wykorzystany. W efekcie końcowym, po wciśnięciu Entera, program nagle by się zakończył, a my nie ujrzelibyśmy kolejnego komunikatu celem potwierdzenia przyjęcia naszej liczby.


To wszystko w tym temacie. Modyfikator gwiazdki potrafi być przydatny przy właściwym formatowaniu danych.

PODOBNE ARTYKUŁY