background image

Ć

wiczenia 15 maja 2012 

 

TABLICE TEKSTOWE 
 
Podobnie  jak  liczby  można  wczytać  jeden  znak,  a  co  z  całym  wyrazem?  Ciąg  znaków  alfanumerycznych 
(string,  po  polsku  łańcuch),  to  znaki  kolejno  zapisane  w  pamięci.  Najlepiej  do  zapisania  użyć  tablicy 
przechowującej znaki (typ char). Kończymy zawsze znakiem specjalnym NULL (‘\0’) 
 
Przykład 
 
#include <cstdlib> 
#include <iostream> 
 
using namespace std; 
 
int main() 

    char ciag_znak[ 10 ] = { 'I', 'N', 'F', 'o ', '-', ' ', 
        'C', '+', '+', '\0' }; 
        char wyraz[ 50 ]; 
     
    cout << "Podaj swoj tekst: "; 
    cin >> wyraz; 
    cout << "Wprowadziles nastepujace znaki: \"" << wyraz 
    << "\"" << endl; 

background image

     
    cout << "Natomiast poprawny ciag znakow wyglada tak: \"" 
    << ciag_znak 
    << "\"" << endl; 
     
     
    system("PAUSE"); 
    return EXIT_SUCCESS; 

Jeśli wprowadzamy tekst o długości n znaków, to znak n+1 będzie zawsze równy 0. Dla większości funkcji, 
które  operują  na  łańcuchach  znaków,  jest  to  informacja,  aby  zakończyć  wyświetlanie  kolejnych  znaków  z 
tablicy, czyli tak oznaczamy koniec tekstu.  
 
char niepoprawana_tablicaZnakow[ 5 ] = { 'i', 'n', 'f ', '', 'C' }
nie posiada znaku NULL, dlatego nie przechowuje łańcucha znaków. 
 
Przykład 
 
#include <cstdlib> 
#include <iostream> 
 
using namespace std; 
 
int main() 

background image


    char ciag_znak[ 40 ]; 
    char tekst[ 20 ] = "uczymy sie C++ "; 
     
    cout << "Podaj swoje imie i nazwisko programisto:) " 
    << endl; 
    cin >> ciag_znak; 
    cout << "Nazywasz sie: " << ciag_znak 
        << endl; 
        
    system("PAUSE"); 
    return EXIT_SUCCESS; 

 
Wczytaliśmy łańcuch za pomocą strumienia cin. Warto zauważyć, że wczytuje on znaki do zmiennej, aż do 
napotkania białego znaku (spacja, tabulator, enter,…). Powyżej napisaliśmy dwa wyrazy oddzielone spacją i 
drugi  nie  został  wczytany.  Pamiętajmy  również,  iż  zmiana  jakiegokolwiek  znaku  w  łańcuchu  na  znak 
zerowy, będzie oznaczało jego skrócenie. 
 

 

OPERACJE NA ŁAŃCUCHACH 

 

Porównywanie łańcuchów znaków 

 

background image

Do porównywania dwóch ciągów znaków należy użyć funkcji strcmp zadeklarowanej w pliku 

nagłówkowym string. Jako argument przyjmuje ona dwa napisy i zwraca wartość ujemną, jeżeli napis 

pierwszy jest mniejszy od drugiego, 0 jeżeli napisy są równe lub wartość dodatnią jeżeli napis pierwszy jest 

większy od drugiego. Ciągi znaków porównywane są na bazie kodów znaków, czyli np. (dla ASCII) "a" jest 

mniejsze od "b", ale jest większe od "B".  

Czasami możemy chcieć porównać tylko fragment napisu, np. sprawdzić czy zaczyna się od jakiegoś 

konkretnego ciągu znaków. W takich sytuacjach pomocna jest funkcja strncmp. W porównaniu do strcmp() 

przyjmuje ona jeszcze jeden argument oznaczający maksymalną liczbę znaków do porównania

 

 
Kopiowanie napisów 

 

Do kopiowania ciągów znaków służy funkcja strcpy, która kopiuje drugi napis w miejsce pierwszego (w 
pierwszym łańcuchu musi być wystarczająco dużo miejsca). 

  

char napis[100]; 

 strcpy(napis, "Ala ma kota."); 

 
Znacznie bezpieczniej jest używać funkcji strncpy, która kopiuje co najwyżej tyle bajtów, ile podano jako 
trzeci parametr. Uwaga! Jeżeli drugi napis jest za długi funkcja nie kopiuje znaku null na koniec pierwszego 
napisu, dlatego zawsze trzeba to robić ręcznie: 

 

background image

char napis[100] = {'\0'}; 

 strncpy(napis, "Ala ma kota.", sizeof(napis) - 1); 

 napis[strlen(napis)]= '\0'; 

 
Łączenie napisów 

 

Do łączenia napisów służy funkcja strcat, która kopiuje drugi napis do pierwszego. Ponownie jak w 
przypadku strcpy musimy zagwarantować, by w pierwszym łańcuchu było wystarczająco dużo miejsca. 

 

   char napis1[80] = "hello "; 

   const const char *napis2 = "world"; 

   strcat(napis1, napis2); 

 

I ponownie jak w przypadku strcpy istnieje funkcja strncat, która skopiuje co najwyżej tyle bajtów ile 
podano jako trzeci argument i dodatkowo dopisze znak null. Przykładowo powyższy kod bezpieczniej 
zapisać jako: 

 

   char napis1[80] = "hello "; 

   const char *napis2 = "world"; 

background image

   strncat(napis1, napis2, sizeof napis1 - 1); 
  
TABLICE WIELOWYMIAROWE 

 

Do tej pory operowaliśmy na tablicach jedno wymiarowych, przyjrzyjmy się jak tworzy i stosuje tablice 
wielowymiarowe. Załóżmy, że chcemy napisać program, która będzie przechowywać określone dane w 
macierzy 
 
Przykład 
 
#include <cstdlib> 
#include <iostream> 
 
using namespace std; 
 
int main() 

    const short LICZBA_Wierszy = 6; 
const short LICZBA_kolumn = 8; 
int i, j; 
    using namespace std; 
        char tab1[ LICZBA_Wierszy ][ LICZBA_kolumn ] = { 
        { '4', '1', '1', '2', '3', '2', '5', '3' }, 
        { '3', '1', '1', '3', '9', '9', '7', '3' }, 

background image

        { '3', '5', '3', '2', '1', '8' , '2', '1'}, 
        { '8', '1', '1', '4', '3', '3', '2', '1' }, 
        { '4', '1', '1', '2', '1', '3', '2', '1' }, 
        { '4', '3', '3', '2', '1', '2', '1', '9' }, 
    }; 
    cout<<" element z ktorego wiersza chcesz wyswietlic? "; 
    cin>>i; 
    cout<<" element z ktorej kolumny chcesz wyswietlic? "; 
    cin>>j; 
    cout<<" element do wyswietlenia to " << tab1[i][j]<<"\n"; 
 
    system("PAUSE"); 
    return EXIT_SUCCESS; 

 
Zadanie 8.4.  
 
Napisz program

który dla tablicy dwuwymiarowej policzy sumę elementów oraz element maksymalny. 

 
Zadanie 9.1 
 
Napisz program, korzystając z tablicy dwuwymiarowej, z tabliczką mnożenia do 100. 

background image

 
Zadanie 9.2 
 
Napisz program (korzystając z tablicy dwuwymiarowej), który dla wczytanego z klawiatury ciągu liczb 
całkowitych wypisze sumę  cyfr każdej z tych liczb.  
 
 
 
PSEUDOLOSOWE LICZBY CAŁKOWITE 

 

Generowanie losowe liczb całkowitych. 

 

Funkcja losująca liczby całkowite pochodzi ze standardowej biblioteki języka C. Bibliotekę, którą należy 
dołączyć jest cstdlib.  
 
Funkcja losująca  po prostu losuje liczbę całkowitą, która mieści się w przedziale od 0 do RAND MAX (jest 
to stała, która zależy od kompilatora i załączonych bibliotek).  
 
Przykład 
 
 
#include <iostream> 
#include <cstdlib> 
int main() 

background image

    cout << "losowanie pierwsze: " << rand() << endl; 
    int liczba = rand(); 
    cout << "losowanie drugie: " << liczba << endl; 
    liczba = rand(); 
    cout << "losowanie trzecie: " << liczba << endl; 
    return 0; 

 
Konfiguracja maszyny losującej 
Jeżeli uruchomimy kilka razy powyższy program to zauważymy, że komputer wylosował nam za każdym 
razem te same liczby. Takie zachowanie oczywiście nie jest pożądane, dlatego też wymagane jest 
skonfigurowanie generatora liczb losowych.  
 
srand( time( NULL ) ); 
 
Powyższą linijkę wystarczy wywołać tylko raz na samym początku programu, kod wygląda teraz tak:  
 
#include <iostream> 
#include <cstdlib> 
#include <ctime> 
int main() 

    srand( time( NULL ) ); 
    cout << "losowanie pierwsze: " << rand() <<  endl; 

background image

    int liczba = rand(); 
    cout << "losowanie drugie: " << liczba <<  endl; 
    liczba = rand(); 
    cout << "losowanie trzecie: " << liczba << :endl; 
    return 0; 

 
Jeżeli potrzebujemy zmienić zakres to wykorzystać musimy działanie modulo i dodawanie. Najpierw 
ustalamy ile liczb mieści się w przedziale z którego chcemy losować, np. 50 liczb. Następnie ustalamy 
pierwszą losowaną liczbę np. 7.  
 
int wylosowana_liczba =( rand() % ile_liczb_w_przedziale ) + startowa_liczba; 
 
a dokładnie:  
  
int wylosowana_liczba =( rand() % 50 ) + 7; 
 
Albo dla liczb z dowolnego przedziału <a,b> wypełnimy nimi tablicę: T[i] = a + rand() % (b - a + 1) 
 
Ostatecznie program losujący liczby z przedziału od 7 do 56 będzie więc wyglądał tak:  
  
#include <iostream> 
#include <cstdlib> 
#include <ctime> 

background image

int main() 

    srand( time( NULL ) ); 
    cout << "losowanie pierwsze: " <<(( rand() % 50 ) + 7 ) << endl; 
    int liczba =( rand() % 50 ) + 7; 
    cout << "losowanie drugie: " << liczba << endl; 
    liczba =( rand() % 50 ) + 7; 
    cout << "losowanie trzecie: " << liczba << endl; 
    return 0; 

 
Zadanie 9.3 
 
Napisz program, który wylosuje pewną ilość liczb (wartość wczytana z klawiatury) z określonego przedziału 
(wartości początku i końca przedziału wczytane z klawiatury). 
 
Zadanie 9.4. (domowe) 
 
Napisać grę, która ma działać następująco: 1. Program losuje liczbę z przedziału od 1 do 1000.  
2. Użytkownik zgaduje liczbę, która została wylosowana.  
3. Jeżeli podana liczba jest za duża (za mała) gra wypisuje stosowny komunikat i powraca do kroku 2.  
4. Jeżeli gracz trafi liczbę wylosowaną to pogram kończy działanie, wypisując na ekran wylosowaną liczbę 
oraz liczbę 'strzałów', które oddał gracz.  
Gra ma być zabezpieczona przed możliwością wprowadzenia błędnych wartości liczbowych.