luni, 25 ianuarie 2016

C#13 Operații cu siruri de caractere și fișiere text

Manevrarea stringurilor

Tipul string este un alias pentru clasa System.String.  Obiectele de tip string încapsulează un șir de caractere în format Unicode. Ca majoritatea obiectelor, stringurile încapsulează  și metode proprii nestatice. Cu aceste metode lucrăm pentru a manipula obiectele de tip șir: copiere, trunchiere, concatenare, găsire și creare subșir, separarea unui string în mai multe substringuri în funcție de apariția unor separatori, transformare în majuscule/minuscule, etc.  Apelul unei metode de acest gen se face după sintaxa uzuală: 

numeSir.NumeMetoda. 

 Obiectele string sunt read only. Întotdeauna se va obține un șir nou în urma modificării unui șir. 

Operații cu fișiere text


 Citirea  și scrierea în fișiere este realizată ca în C++, sub formă de fluxuri de intrare/ieșire (stream-uri). Particularitatea stream-urilor este aceea că nu pot manipula decât șiruri de caractere (string-uri). 
Spre deosebire de C++, în C# nu există operatorii >>  și <<.

Se folosesc în schimb obiecte de tipul StreamReader (pentru stream de citire) și StreamWriter (pentru stream de scriere).


Exemplul care urmează implementează diverse operații cu șiruri C#, inclusiv funcția Split, și operații de intrare/ieșire cu fișiere text.


namespace StringuriSiFisiereText
{
    class Program
    {
        static void Main()
        {
            string s1 = "Salut", s2 = "salut";
            if (s1 != s2)
                Console.WriteLine("s1!=s2");
            Console.WriteLine(s2.ToUpper());    //afiseza SALUT. metoda ToUpper face majuscule
            s1 += s2;
            Console.WriteLine(s1);              //afiseaza Salutsalut
            string s = s1.Insert(5, " ");          // metoda Insert inserează un caracter pe poziția specificată
            Console.WriteLine(s);               //afiseza Salut salut
            s = s.Substring(6, 3);                  // metoda Substring decupează un subșir din locul specificat
            Console.WriteLine(s);               //afiseaza sal
            // citirea unui sir de numere separate prin spatii de la tastatura
            // metoda Split a obiectelor string
            //metoda Parse a tipurilor numerice pentru conversie din string
            string linie = Console.ReadLine();
            string[] subsiruri = linie.Split(' ');  //metoda Split creează un tablou de șiruri

                                                                  //în fincție de apariția separatorilor specificați, aici spațiu.
            int nr;
            foreach (string subsir in subsiruri)
            {
                nr = int.Parse(subsir);   //convertește în numere
                Console.Write(nr + "...");
            }
            //deschidere fisiere de intrare si  iesire
            StreamReader fin = new StreamReader("numere.in"); 
            // fisierele se gasesc in
            // subdirectorul /bin/Debug al directorului
            // care contine programul sursa
            StreamWriter fout = new StreamWriter("numere.out");
            string articol=null;
            string[] campuri=null;
            int numar;
            //citeste cate un articol = linie din fisier
            //pana la sfarsitul fisierului
            while ((articol = fin.ReadLine()) != null)
            {
                campuri = articol.Split(' '); //desparte linia in subsiruri
                foreach (string camp in campuri)
                {
                    if (camp != "") //subsirurile vide aparar daca sunt mai multi delimitatori unul dupa altul
                    {
                        numar = int.Parse(camp); //obtine un numar
                        fout.Write("{0,-5}", numar);   //scriere cu format. Aliniere la stânga, marime câmp= 5
                        Console.WriteLine("{0}", numar);
                    }
                }
                fout.WriteLine(); //scrie sfarsit de linie
            }
            fin.Close();
            fout.Close();
            Console.ReadKey();
        }
    }
}

 

 

 


duminică, 10 ianuarie 2016

C# 12 - Evenimente

Ce este un eveniment


Interfețele grafice actuale cer ca un anumit program să  răspundă  la evenimente. Un eveniment poate fi de exemplu apăsarea unui buton, terminarea transferului unui fișier, selectarea unui meniu, etc; pe scurt, se întâmplă  ceva la care trebuie să se dea un răspuns.

Alte clase/ obiecte  pot fi interesate să răspundă  la aceste evenimente. Modul în care vor reacționa va fi diferit de la caz la caz,  iar obiectul care semnalează evenimentul (ex: un obiect de tip buton, la apăsarea lui) nu trebuie să știe modul în care se va răspunde. Butonul va comunica faptul că a fost apăsat, iar clasele interesate în acest eveniment vor reacționa fiecare în mod specific.

Publicarea și subscrierea


În C#, orice obiect poate să publice un set de evenimente la care alte clase pot să subscrie. Când obiectul care a publicat evenimentul îl și semnalează, toate obiectele care au subscris la acest eveniment sunt notificate. În acest mod se definește o dependență de tip one–to–many între obiecte astfel încât dacă un obiect își schimbă starea, atunci toate celelalte obiecte dependente sunt notificate și modificate automat. De exemplu, un buton poate să notifice un număr oarecare de observatori atunci când a fost apăsat. Butonul va fi numit publicator (publisher) deoarece publică evenimentul Click iar celelalte clase sunt numite abonați (subscriber)  deoarece ele subscriu la evenimentul Click.

 Evenimente și delegați


 Tratarea evenimentelor în C# se face folosind delegați. Clasa ce publică definește un delegat pe care clasele abonate trebuie să îl implementeze. Când evenimentul este declanșat, metodele claselor abonate vor fi apelate prin intermediul delegatului. Metodele care răspund la un eveniment se numesc event handlers. Declararea unui eveniment se face astfel:

event tip nume–eveniment








Descrierea exemplului


Clasa  CeasDigital definește un eveniment cu numele tact asociat delegatului Timp. Metoda Declansator lansează la fiecare 3 secunde un apel către evenimentul tact, cu alte cuvinte face un apel la lista de subscripție a delegatului Timp.
Avem așadar 3 entități asociate care funcționează legat:
- un delegat (Timp, care are tipul void și nu are parametri)
- un eveniment (tact, asociat delegatului Timp)
- o metodă de gestionare a producerii evenimentelor de tip tact (Declanșator).

În continuare apar clasele care subscriu la acest eveniment. Ele sunt clasele Cartier și Rolex. Fiecare din ele definește metoda proprie de tratare a evenimentului, metodă numită handler sau event-handler. Handlerele trebuie să fie compatibile cu  delegatul Timp, respectiv să returneze tipul void și să nu aibă parametri.


În programul principal se instanțiază câte un obiect din fiecare clasă, se face subscrierea handlerelor la lista evenimentului  și se lansează în execuție threadul - respectiv rutina care declanșează evenimentele.

namespace Evenimente
{
    public delegate void Timp(); //declarare tip delegat
    //declararea clasei publisher
    public class CeasDigital
    {
        public event Timp tact; //declarare eveniment de tipul Timp cu numele tact
        public void Declansator() //cod care produce/declanseza evenimentele
        {
            while (true)
            {
                //executia programului se suspenda 3 secunde
                System.Threading.Thread.Sleep(3000);
                //verificam daca exista metode subscrise in lista evenimentului
                if (tact != null)
                    tact();
            }
        }
    }
    //clase abonati
    class Rolex
    {
        public void HanlerRolex()
        {
            Console.WriteLine("Ceasul Rolex, notificat la {0}", DateTime.Now);
        }
    }
    class Cartier
    {
        public void HandlerCartier()
        {
            Console.WriteLine("ceasul Cartier, notificat la {0}", DateTime.Now);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            CeasDigital cd = new CeasDigital();
            Rolex r = new Rolex();
            Cartier c = new Cartier();
            // subscrierea claselor Rolex si Cartier la eveniment
            cd.tact += c.HandlerCartier;
            cd.tact += r.HanlerRolex;
            //declanseaza procesul
            cd.Declansator();
        }
    }
}