© Krzysztof Urbański 2011
1
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.)
#include <stdio.h>
int main()
{
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);
return 0;
}
Przykład 2. (modyfikuj kod, aby zrealizowa
ć
punkt 6.)
#include <stdio.h>
int main()
{
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
2
printf("%08d<CR>\n", -i);
return 0;
}
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
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.
Bez uzupełniania
spacja
(' ')
Uzupełnienie pola spacjami, jeśli użyte
jednocześnie z flagą ‘-‘, to ignorowane.
Bez uzupełniania
#
Dla formatów o, x, X flaga ‘#’ poprzedza liczbę
ciągiem 0, 0x, 0X, (zgodnie z regułami języka C).
Bez uzupełniania
Dla formatów e, E, f, a ,A flaga ‘#’ wymusza
pojawienie się separatora dziesiętnego.
Separator dziesiętny występuje tylko gdy
liczba zawiera część ułamkową.
Dla formatów g, G, flaga ‘#’ wymusza pojawienie
się separatora dziesiętnego i wyłącza obcinanie zer
na końcu części ułamkowej.
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:
#include <stdio.h>
int main()
{
int n = 0;
printf("Ile razy? ");
if(1 == scanf("%d", &n) && n > 0)
{
while(n--)
{
printf("Nie bede rozmawial na lekcji.\n");
}
}
return 0;
}
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
3
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
4
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
5
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
6
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 :
#include <stdio.h>
int main()
{
int n = 0;
for (n=0; n <= 100000; n++)
printf("%d ", n);
return 0;
}
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
7
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