Język C i C++. Podstawy Materiały do samodzielnego opanowania, ale także propozycja zadań na zajęcia laboratoryjne Zagadnienia do opanowania 1) Czym jest standardowe wejście-wyjście (stdio)? 2) Czym może być standardowe wejście (stdin). A standardowe wyjście (stdout)? 3) Na czym polega i jak zrealizować przekierowanie strumienia stdin, stdout, stderr? 4) Zapoznaj się z dokumentacją funkcji printf( )/scanf( ), fprintf( )/fscanf( ), putchar( )/getchar(), puts()/gets(). 5) Sprawdź, w jaki sposób działa formatowanie w printf przy użyciu formatów d, i, o, x, X, e, f, g, c, s. 6) Do czego służą dodatkowe modyfikatory (.width, precision, padding)? 7) Jak wyświetlić wartości zmiennych typu int, short, char, unsigned char, long, float, double, char*? Przykład 1. (modyfikuj kod, aby zrealizować punkty 5., 7.) int i = 255; printf("d: %d\n", i); printf("i: %i\n", i); printf("o: %o\n", i); printf("x: %x\n", i); printf("x: %X\n", i); Przykład 2. (modyfikuj kod, aby zrealizować punkt 6.) int i = 65534; printf("%d<cr>\n", i); printf("%+d<cr>\n", i); printf("%8d<cr>\n", i); printf("%-8d<cr>\n", i); printf("%.8d<cr>\n", -i); Krzysztof Urbański 2011 1
printf("%08d<cr>\n", -i); Specyfikacje ciągu formatującego dla printf( ): %[flags] [width] [.precision] [h l ll I I32 I64]type flag Znaczenie Domyślnie (bez flagi) Justowanie do lewej krawędzi pola. Justowanie prawostronne + Znak +/- przed liczbą Znak ( ) tylko przed liczbami ujemnymi 0 spacja (' ') # Zera wiodące (poprzedzające liczbę). Jeśli jednocześnie wystapi flaga -, to flaga 0 zostanie zignorowana. Dla d,i,u,x,x,o jeśli ustawiona zostanie precyzja (.),to flaga 0 zostanie zignorowana. Uzupełnienie pola spacjami, jeśli użyte jednocześnie z flagą -, to ignorowane. Dla formatów o, x, X flaga # poprzedza liczbę ciągiem 0, 0x, 0X, (zgodnie z regułami języka C). Dla formatów e, E, f, a,a flaga # wymusza pojawienie się separatora dziesiętnego. Dla formatów g, G, flaga # wymusza pojawienie się separatora dziesiętnego i wyłącza obcinanie zer na końcu części ułamkowej. Bez uzupełniania Bez uzupełniania Bez uzupełniania Separator dziesiętny występuje tylko gdy liczba zawiera część ułamkową. Separator dziesiętny występuje tylko gdy liczba zawiera część ułamkową. Zera na końcu części ułamkowej nie są wyświetlane. Przekierowanie stdin, stdout Każda aplikacja używająca funkcji stdio może zostać zmuszona do współpracy z mechanizmami przekierowania strumieni wejścia/wyjścia. Weźmy przykładowy kod: int n = 0; printf("ile razy? "); if(1 == scanf("%d", &n) && n > 0) while(n--) printf("nie bede rozmawial na lekcji.\n"); Po skompilowaniu (w dowolnym środowisku programistycznym) efektem końcowym będzie plik EXE. Jeśli uruchomisz ten program z poziomu IDE, przykładowy wynik może być taki: Krzysztof Urbański 2011 2
1) Menu Start Uruchom, wpisz cmd i naciśnij Enter. Uruchomi się konsola tekstowa (kolory mogą być inne, zależnie od tego jakie masz ustawienia systemowe). 2) Znajdź na dysku, w katalogu, w którym założyłeś projekt, wynik kompilacji i linkowania (plik o rozszerzeniu.exe). 3) Myszką złap ten plik, przeciągnij i upuść w okienku konsoli cmd.exe. Pełna ścieżka i nazwa pliku zostanie automatycznie wklejona do okienka. Naciśnij ENTER aby uruchomić ten program. Do tego momentu wygląda to bardzo podobnie jak normalne uruchomienie programu z poziomu IDE. 4) Naciśnij strzałkę w górę lub powtórz czynność z kroku (3) aby ponownie wyświetlić pełną nazwę pliku. Nie uruchamiaj go jeszcze! 5) Dopisz > wynik.txt na końcu linijki i naciśnij Enter. 6) Wpisz liczbę, np. 999 i naciśnij Enter 7) Wyświetl w notatniku plik o nazwie wynik.txt Krzysztof Urbański 2011 3
Zamiast w konsoli tekstowej, wyniki wyświetlane przez program pojawiły się w pliku którego nazwę podaliśmy za znakiem >. Niestety pytanie Ile razy? też się pojawiło w pliku z wynikami. Jak tego uniknąć? Sięgnij do zagadnień 3, 4! Na podobnej zasadzie zamiast wpisywać informacje z klawiatury, można je wcześniej przygotować w pliku i przekierować zawartość tego pliku do naszej aplikacji. Uruchomiony program myśli, że informacje wpisywane są z klawiatury, podczas gdy w rzeczywistości mogą pochodzić z innego źródła danych zgodnego z mechanizmami stdio. 1) przygotuj plik o nazwie np. dane.txt zawierający w jednej linii tekstu liczbę, np. 123456. 2) Podobnie jak poprzednio, uruchom własną aplikację EXE tym razem dopisując na końcu: < dane.txt > wyniki.txt Krzysztof Urbański 2011 4
Praktycznie bez dodatkowego wysiłku, posługując się mechanizmami wbudowanymi w większość współczesnych systemów operacyjnych, posłużyliśmy się plikami tekstowymi z danymi wejściowymi oraz jesteśmy w stanie produkować w ułamku sekundy pliki tekstowe z wynikami. Wystarcza do tego znajomość zasady formatowania stdout oraz przekierowania strumieni wejścia/wyjścia. Krzysztof Urbański 2011 5
Zadanie dla wszystkich Wyprodukuj w pliku tekstowym tabelkę liczb dziesiętnych, ósemkowych i szesnastkowych z zakresu 0..100000 w czytelnej formie, preferowana postać: Wskazówka: wyświetlenie wszystkich liczb z tego zakresu w konsoli tekstowej można osiągnąć w kilku linijkach następującego kodu języka C : int n = 0; for (n=0; n <= 100000; n++) printf("%d ", n); Pętlę for dokładnie poznamy na kolejnych zajęciach, ale w uproszczonej postaci możesz jej używać już teraz. Zadanie dla zaawansowanych Używając zagnieżdżonej pętli for oraz mechanizmów formatowanego stdout, wyprodukuj tabliczkę mnożenia [0x00.. 0x1F] [0x00.. 0x1F] (tabliczka mnożenia w systemie szesnastkowym, podobna do klasycznej, dziesiętnej tabliczki mnożenia). Krzysztof Urbański 2011 6
Preferowany rezultat: 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 ==== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== 1 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 2 2 4 6 8 A C E 10 12 14 16 18 1A 1C 1E 20 22 24 3 3 6 9 C F 12 15 18 1B 1E 21 24 27 2A 2D 30 33 36 4 4 8 C 10 14 18 1C 20 24 28 2C 30 34 38 3C 40 44 48 5 5 A F 14 19 1E 23 28 2D 32 37 3C 41 46 4B 50 55 5A 6 6 C 12 18 1E 24 2A 30 36 3C 42 48 4E 54 5A 60 66 6C 7 7 E 15 1C 23 2A 31 38 3F 46 4D 54 5B 62 69 70 77 7E 8 8 10 18 20 28 30 38 40 48 50 58 60 68 70 78 80 88 90 9 9 12 1B 24 2D 36 3F 48 51 5A 63 6C 75 7E 87 90 99 A2 a A 14 1E 28 32 3C 46 50 5A 64 6E 78 82 8C 96 A0 AA B4 b B 16 21 2C 37 42 4D 58 63 6E 79 84 8F 9A A5 B0 BB C6 c C 18 24 30 3C 48 54 60 6C 78 84 90 9C A8 B4 C0 CC D8 d D 1A 27 34 41 4E 5B 68 75 82 8F 9C A9 B6 C3 D0 DD EA e E 1C 2A 38 46 54 62 70 7E 8C 9A A8 B6 C4 D2 E0 EE FC f F 1E 2D 3C 4B 5A 69 78 87 96 A5 B4 C3 D2 E1 F0 FF 10E 10 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 100 110 120 11 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 110 121 132 12 12 24 36 48 5A 6C 7E 90 A2 B4 C6 D8 EA FC 10E 120 132 144 Rozwiązanie tego zadania typowo zajmuje kilkanaście wierszy kodu, mniej więcej wygląda tak: Rozmycie obrazka jest celowe, proszę NIE regulować monitora, ostry kod macie napisać samodzielnie. Obrazek jest tylko poglądowy, aby móc oszacować, ile tego kodu powinno być. Większość kodu to ozdobniki w postaci ASCII-art (nagłówki tabelki, linie siatki), ale cała zabawa właśnie na tym polega, żeby wykazać się umiejętnością sprytnego zaprogramowania tych gadżetów. Zadanie na 5.5 Używając wyłącznie funkcji printf( ) i stdio opracuj aplikację, na wyjściu której otrzymasz przykładowy efekt: http://demotywatory.pl/2660535/prawdziwy-artysta Krzysztof Urbański 2011 7