Tuesday, July 3, 2012

[C++]Functii odbc operare baza date access 2003-2007

Salut, va prezint un alt proiect mai vechi, de aceasta data legat de operarea cu bazele de date access - asta aveam nevoie la timpul respectiv. Sunt doar 4 functii simple una pentru "select" din sql, alta pentru "insert", una pentru recuperarea erori/erorilor si una pentru a face curat dupa celelalte 3 functii. Functiile sunt foarte simple, dar pentru proiectul la care am avut nevoie la momentul respectiv si-au facut treaba cu brio. Pentru a le utiliza aveti nevoie sa legati (link) libraria odbc32. Functiile se folosesc de api-ul ODBC, si pot fi modificate pentru a putea rula cu orice tip de baza de date la care va puteti conecta cu ODBC. Pentru a le utiliza nu trebuie decat sa adaugati cele 2 fisiere proiectului vostru.

functii_odbc.h
#ifndef FUNCTII_ODBC_H_INCLUDED
#define FUNCTII_ODBC_H_INCLUDED

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>


int select(std::string dns, int numarCampuri, std::string querry, std::vector<std::vector< std::string> >& array, std::string& erroare);
void getErrors(SQLSMALLINT type,SQLHANDLE handle, std::string& error);
void freeDbResources(HSTMT& hStmt, HENV& hEnv, HDBC& hDbc);
int insert(std::string dns, std::string num_Tabel, std::vector<std::string> Campuri, std::vector<std::string> Valori, std::string& error);

#endif // FUNCTII_ODBC_H_INCLUDED


functii_odbc.cpp
#include "functii_odbc.h"
/**
 * Lista argumente:
 * string dns = adresa fisierului acces mdb/accdb pe hard-disk
 * numarCampuri = numarul de campuri care urmeaza a fi selectate prin querry-ul respectiv
 * vector<vector<string> >& array = este un vector de vectori de stringuri, trimis prin referinta care va contine datele extrase
 * in felul urmator: array[0][0] va fi prima coloana returnata pe primul rand
 * array[0][1] va fi a 2-a coloana
 * array[0][2] va fi a 3-a coloana smd
 * iar array[x][0], x va desemna randul de date extrase
 * string& eroare = va contine mesajele de eroare, in situatia in care apare o eroare in executia functiei sau a querry-ului atunci aceasta va fi salvata in acest string
 * Functia are doar 2 valori de return 1 = succes in executarea querry-ului, sau -1 eroare
 * Functia face doar cateva verificari de baza in privinta corectitudinii querry-ului
 * De asta trebuie sa se asigure utilizatorul inainte
 * Functia va verifica doar daca exista un posibil insert in querry caz in care iese.
 */
using namespace std;
int select(string dns, int numarCampuri, string querry, vector<vector<string> >& array, string& erroare)
{
    if(querry.find("SELECT") == string::npos || querry.find("INSERT") != string::npos)
    {
        erroare = "Nu ai introdus o comanda de select;";
    }
    else
    {
        SQLCHAR valoareCustomers[numarCampuri][128];
        HSTMT querryStmt;
        string tempNume;
        int retCode[numarCampuri];
        HENV hEnv;
        HDBC hDbc;
        RETCODE rc;
        int len = querry.size();
        char szConnStrOut[255];
        int iConnStrLength2Ptr;
        char szDSN[256] = "Driver={Microsoft Access Driver (*.mdb)};DSN='';DBQ=";
        unsigned char* statementQuerry = (unsigned char*)querry.c_str();
        //vStrArray.clear(); // golim vectorul primit ca container de output (este datoria utilizatorului sa se asigure ca nu are nimic important in vector inainte de a fi trimis acestei functii
        strcat(szDSN, dns.c_str());
        rc = SQLAllocEnv(&hEnv);
        if(!SQL_SUCCEEDED(rc))
        {
            erroare = "Nu am putut aloca Envorimentul.";
            cout << "Nu am putut aloca envorimentul.";
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }
        rc = SQLAllocConnect(hEnv, &hDbc);
        if(!SQL_SUCCEEDED(rc))
        {
            erroare = "Nu am putut aloca conexiunea.";
            cout << "Nu am putut aloca conexiunea.";
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }

        rc = SQLDriverConnect(hDbc, NULL, (SQLCHAR*)szDSN,
                            SQL_NTS, (SQLCHAR*)szConnStrOut,
                            255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
        if(!SQL_SUCCEEDED(rc))
        {
            getErrors(SQL_HANDLE_DBC , hDbc, erroare);
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }
        rc = SQLAllocStmt(hDbc, &querryStmt);
        if(!SQL_SUCCEEDED(rc))
        {
            erroare = "Nu am putut aloca statementul.";
            cout << "Nu am putut aloca statementul.";
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }
        rc = SQLPrepare(querryStmt, statementQuerry, SQL_NTS);
        if(!SQL_SUCCEEDED(rc))
        {
            erroare = "Nu am putut pregatii statementul.";
            cout << "Nu am putut pregatii statementul.";
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }
        for(int i = 0; i < numarCampuri; i++)
        {
           rc = SQLBindCol(querryStmt, (i + 1), SQL_C_CHAR, valoareCustomers[i], 128, (SQLINTEGER*)&retCode[i]);
           if(!SQL_SUCCEEDED(rc))
            {
                erroare = "Nu am putut bindui coloana.";
                cout << "Nu am putut bindui coloana.";
                freeDbResources(querryStmt, hEnv, hDbc);
                return -1;
            }
        }
        cout << endl << endl << statementQuerry << endl;
        rc = SQLExecute(querryStmt);
        if(SQL_ERROR == rc || SQL_SUCCESS_WITH_INFO == rc)
        {
            cout << "Eroare in executare statement, sau SQL_SUCCESS_WITH_INFO";
            erroare = "Eroare in executare statement, sau SQL_SUCCESS_WITH_INFO";
            getErrors(SQL_HANDLE_STMT, querryStmt, erroare);
            return -1;
        }
        else if(SQL_NEED_DATA == rc)
        {
            cout << "SQL_NEED_DATA.";
            erroare = "SQL_NEED_DATA.";
            getErrors(SQL_HANDLE_STMT, querryStmt, erroare);
            return -1;
        }
        else if(SQL_STILL_EXECUTING == rc)
        {
            cout << "SQL_STILL_EXECUTING.";
            erroare = "SQL_STILL_EXECUTING.";
            getErrors(SQL_HANDLE_STMT, querryStmt, erroare);
            return -1;
        }
        else if(SQL_NO_DATA == rc)
        {
            cout << "SQL_NO_DATA.";
            erroare = "SQL_NO_DATA.";
            getErrors(SQL_HANDLE_STMT, querryStmt, erroare);
            return -1;
        }
        else if(SQL_INVALID_HANDLE == rc)
        {
            cout << "SQL_INVALID_HANDLE.";
            erroare = "SQL_INVALID_HANDLE";
            getErrors(SQL_HANDLE_STMT, querryStmt, erroare);
            return -1;
        }
        rc = SQLFetch(querryStmt);
        if(SQL_SUCCESS == rc)
        {
            while(SQL_SUCCEEDED(rc))
            {
                vector<string> vString;
                string temp;
                for(int i = 0; i < numarCampuri; i++)
                {
                    temp = (char*)valoareCustomers[i];
                    vString.push_back(temp);
                }
                array.push_back(vString);
                rc = SQLFetch(querryStmt);
            }
            freeDbResources(querryStmt, hEnv, hDbc);
            return 1;
        }
        else if(SQL_SUCCESS_WITH_INFO == rc || SQL_ERROR == rc)
        {
            cout << "Nu am putut executa SQLFetch.\n";
            cout << "Nu am putut executa SQLFetch.\n";
            getErrors(SQL_HANDLE_STMT, querryStmt, erroare);
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }
        else if(SQL_STILL_EXECUTING == rc)
        {
            cout << "Inca se executa statementul.\n";
            erroare = "Inca se executa statementul.\n";
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }
        else if(SQL_NO_DATA == rc)
        {
            cout << "Nu exista date de returnat.\n";
            erroare = "Nu exista date de returnat.\n";
            freeDbResources(querryStmt, hEnv, hDbc);
            return -1;
        }
    }
    return -1;
}



/**
 * Functia preia prin referinta handle-urile pentru conexiune, mediu si statement si le elibereaza
 */
void freeDbResources(HSTMT& hStmt, HENV& hEnv, HDBC& hDbc)
{
    SQLFreeStmt(hStmt, SQL_UNBIND);
    SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    SQLDisconnect(hDbc);
    SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}


/**
 * Functia preia datele necesare pentru a putea prelua o eroare legata de un handle pentru conexiune, statement sau mediu
 * SQLSMALLINT type poate fi: QL_HANDLE_DBC, SQL_HANDLE_DBC_INFO_TOKEN, SQL_HANDLE_DESC, SQL_HANDLE_ENV, SQL_HANDLE_STMT
 * SQLHANDLE handle va fi de fapt handle-ul pentru care aven nevoie sa preluam eroarea
 * string& eroare = va tine textul erori
 * Functia preia doar erorile care pot fi preluate prin SQLGetDiagRec.
 * Mai multe informatii despre SQLGetDiagRec aici: http://msdn.microsoft.com/en-us/library/windows/desktop/ms716256(v=vs.85).aspx
 */
void getErrors(SQLSMALLINT type,SQLHANDLE handle, string& eroare)
{
    SQLINTEGER i = 1;
    SQLINTEGER native; // codul nativ al erori ( depinde de sistemul de operare si de driver
    SQLCHAR state[7]; // starea driverului mai multe informatii despre state : http://msdn.microsoft.com/en-us/library/windows/desktop/ms716412(v=vs.85).aspx
    SQLCHAR text[256]; // textul erori
    SQLSMALLINT len; // marimea textului erori
    SQLRETURN ret; // stocheaza raspunsul functiei SQLGetDiagRec
    ret = SQLGetDiagRec(type, handle, i, (SQLCHAR*)state, &native, (SQLCHAR*)text, sizeof(text), &len );
    if(SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret)
    {
        stringstream buffer(stringstream::in | stringstream::out);
        string temp;
        eroare = "Eroare:\n";
        eroare.append("State: ");
        cout << "State: " << state << endl;
        buffer << state;
        buffer >> temp;
        eroare.append(temp);
        buffer.flush();
        string temp3((char*)text);
        eroare.append("\nTextul eroarei: ");
        eroare.append(temp3);
        buffer.flush();
        cout << "Textul erori: " << text << endl;
    }
    else if(SQL_ERROR == ret)
    {
        eroare = "eroare Raporting: SQLGetDiagRec returneaza o eroare.\n";
    }
    else if(SQL_INVALID_HANDLE == ret)
    {
        eroare = "eroare Raporting: Handleul furnizat pentru preluarea erori a fost incorect.\n";
    }
    else if(SQL_NO_DATA == ret)
    {
        eroare = "eroare Raporting: Nu au fost date de returnat.\n";
    }
}

/**
 * Lista argumente:
 * string dns = adresa pe disk a fisierului access
 * string num_Tabel = numele tabelului in care se face inserarea
 * vector<string> Campuri = Un vector ce contine campurile in care se va face inserarea
 * vector<string> Valori = Un vector cu valorile ce vor fi introduse in fiecare camp
 * string& eroare va tine textul oricarei posibile erori
 * Pentru cei doi vectori marimea lor trebuie sa fie identica.
 * Exemplu Campuri va contine stringurile "Nume", "Prenume" "telefon"
 * vectorul Valori va contine "ION", "VASILE", "02345241590"
 * Functia are doar 2 valori de return 1 = succes in inserarea datelor, sau -1 eroare
 */
int insert(string dns, string num_Tabel, vector<string> Campuri, vector<string> Valori, string& eroare)
{
    //Incepem pregatirea statmentului
    string comanda = "INSERT INTO ";
    string comanda2 = ") VALUES ('";
    string comanda3 = ");";
    string campuri_tabel;
    string campuri_valori;
    //verificam daca numarul de campuri si de valori e identic
    if(Campuri.size() != Valori.size())
    {
        eroare = "Numarul de campuri si de valori nu este identic. Pentru ca inserarea sa se poata efectua este necesar ca cele 2 sa fie identice.\n";
        return -1;
    }
    // pregatim lista cu campurile in care se introduc datele
    for(unsigned int i = 0; i < Campuri.size(); i++)
    {
        if(i == (Campuri.size() - 1))
        {
            campuri_tabel.append(Campuri[i]);
            //campuri_tabel.append(")");
        }
        else
        {
            campuri_tabel.append(Campuri[i]);
            campuri_tabel.append(", ");
        }
    }
    // pregatim lista cu valorile de introdus
    for(unsigned int i = 0; i < Valori.size(); i++)
    {
        if(i == (Valori.size() - 1))
        {
            campuri_valori.append(Valori[i]);
            campuri_valori.append("'");
        }
        else
        {
            campuri_valori.append(Valori[i]);
            campuri_valori.append("', '");
        }
    }
    string sql_statement;
    sql_statement.append(comanda);
    sql_statement.append(num_Tabel);
    sql_statement.append("(");
    sql_statement.append(campuri_tabel);
    sql_statement.append(comanda2);
    sql_statement.append(campuri_valori);
    sql_statement.append(");");
    // am terminat pregatirea statementului

    // pregatim conexiunea la bd
    // inceput definitii variabile necesare conexiunii la db
    HENV hEnv;
    HDBC hDbc;
    HSTMT hStmt;
    RETCODE rc;
    char szConnStrOut[255];
    int iConnStrLength2Ptr;
    char szDSN[256] = "Driver={Microsoft Access Driver (*.mdb)};DSN='';DBQ=";
    // incheiere definitii
    // Initiem conexiunea
    strcat(szDSN, dns.c_str());
    rc = SQLAllocEnv(&hEnv);
    if(!SQL_SUCCEEDED(rc))
    {
        eroare = "Nu am putut aloca Envorimentul.";
        cout << "Nu am putut aloca envorimentul.";
        return -1;
    }
    rc = SQLAllocConnect(hEnv, &hDbc);
    if(!SQL_SUCCEEDED(rc))
    {
        eroare = "Nu am putut aloca conexiunea.";
        cout << "Nu am putut aloca conexiunea.";
        return -1;
    }

    rc = SQLDriverConnect(hDbc, NULL, (SQLCHAR*)szDSN,
                           SQL_NTS, (SQLCHAR*)szConnStrOut,
                           255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
    if(!SQL_SUCCEEDED(rc))
    {
        getErrors(SQL_HANDLE_DBC , hDbc, eroare);
        freeDbResources(hStmt, hEnv, hDbc);
        return -1;
    }
    rc = SQLAllocStmt(hDbc, &hStmt);
    rc = SQLPrepare(hStmt, (SQLCHAR*)sql_statement.c_str(), SQL_NTS);
    rc = SQLExecute(hStmt);
    if(!SQL_SUCCEEDED(rc))
    {

        eroare = "Inserarea nu a putut fi efectuata.";
        cout << "Inserarea nu a putut fi efectuata.";
        getErrors(SQL_HANDLE_STMT, hStmt, eroare);
        freeDbResources(hStmt, hEnv, hDbc);
        return -1;
    }
    else if(SQL_SUCCEEDED(rc))
    {
        freeDbResources(hStmt, hEnv, hDbc);
        return 1;
    }
    return -1;
}
Sper sa va fie utile.

[C++]Generator de lista cuvinte(passwords)

Va prezint un proiect ceva mai vechi de al meu, acesta a fost scris in principiu pentru a genera toate combinatiile, ordonat, ale unei liste de caractere. Generarea cuvintelor se face incepand cu un cuvant format din prima litera a sirului * lungimea dorita a cuvantului si se va termina cu un cuvant format din ultima litera din sir * lingimea cuvantului cerut.De exemplu pentru un sir de caracter a-z si lungimea cuvantului de 5 caractere, functia va incepe cu "aaaaa" si va termina cu "zzzzz". Generarea se face printr-o functie recursiva, intr-un thread separat pentru a nu bloca interfata aplicatiei. Sistemul nu este nici cel mai eficient si nici cel mai rapid, totusi poate fi folosit ca punct de plecare. Proiectul a fost scris utilizant framework-ul wxWidgets, inclusiv modelul de threading al acestuia. Puteti compila cele 4 fisiere cpp/h adaugandu-le unui proiect menit sa compileze o aplicatie wxWidgets. In mod normal ar trebui sa poata fi compilata chiar si pe linux cu un minim de modificari, totusi nu am testat la momentul respectiv. Proiectul a fost postat initial aici, unde puteti si adresa intrebari daca aveti. Link-ul direct pentru a descarca proiectul se gaseste aici.

Friday, June 22, 2012

[c++]Crypted ip to ip chat

[RO]
Va prezint un program de chat securizat. Traficul dintre cele 2 persoane care vorbesc este criptat cu ajutorul algoritmului RSA, care este un algoritm te criptare cu cheie publica/privata.Libraria utilizata este crypto++ iar pentru interfata grafica am utilizat libraria wxWidgets versiunea 2.8.12. Mai jos voi adauga un link de download a proiectului, acesta a fost facut cu ajutorul ide-ului Code Blocks. Proiectul poate fi compilat cu orice alt ide prin adaugarea celor 4 fisiere cpp/h unui proiect gol creat de voi, atat timp cat proiectul este setat corect pentru a putea compila un proiect wxWidgets. Puteti utiliza sample-urile care vin o data cu libraria wxWidgets ca punct de start. Pentru crypto++ sugerez sa folositi libraria statica. Proiectul in romana

[EN]
I present you a secure chat. The trafic between the 2 people talking is encrypted with the help of the RSA algorithm, which is a public/private key encryption algorithm. The library used is crypto++, and for the graphic interface i used the wxWidgets library version 2.8.12. Below i will ad a download link for the project, which was created with the help of Code Blocks ide. The project can be compiled with any other ide by adding the 4 cpp/h files to an empty project you create, as long as the project is correctly set up to compile wxWidgets application. You can use the samples that come along the wxWidgets librari as a starting point. For crypto++ i sugest you use the static library. English project

Tuesday, September 14, 2010

[C++]Conversie numere scrise in cifre arabe si viceversa

Salut, mai jos va voi prezenta u bucata de cod scrisa in C++, care poate fi folosita in diferite aplicatii. Codul de mai jos v-a prelua de la utilizator fie o cifra intre 0 si 9 fie corespondentul lor scris adica : zero, unu, doi, si v-a afisa valoarea convertita, adica daca utilizatorul va introduce cifra 5 programul v-a afisa "cinci" . Dupa va voi explica ce face si codul in sine.
#include <iostream>
#include <vector>
#include <conio.h>
#include <string>
#include <stdlib.h>
 
using namespace std;
 
 
int main()
{    
   char din_nou = ' ';
   const int marime_vector = 10;
   int numar_de_control = 0; //folosit pentru controlul buclelor(loop's)
   string temp; // stocheaza imput-ul utilizatorului
   vector<string> numere(marime_vector);
   numere[0] = "zero";
   numere[1] = "unu";
   numere[2] = "doi";
   numere[3] = "trei";
   numere[4] = "four";
   numere[5] = "cinci";
   numere[6] = "sase";
   numere[7] = "sapte";
   numere[8] = "opt";
   numere[9] = "noua";
   do
   {
      numar_de_control = 0; // resetam numarul de control
      cout << "Acest program v-a prelula de la utilizator un input,\n";
      cout << "precum '7' sau 'sapte' si v-a printa pe ecran corespondentul lui.\n";
      getline(cin,temp); // preluam imput de la utilizator
 
      if(temp.size() == 1) // utilizatorul introduce un singur caracter
      {
         if((int(temp[0]) >= 48 && int(temp[0] <= 57)) || (temp[0] >= 0 && temp[0] <= 9)) // check if it's an number
         {
            for(int i = 0; i < 10; i++) // cautam numarul in vector
            {
               if(atoi(temp.c_str()) == i)
               {
                  cout << "Ai introdus " << temp << " adica " << numere[i] << "." << endl;
 
               }
 
            }
         }
         else
         {
            cout << "Nu ai introdus o cifra.\n";
         }
      }
      if(temp.size() > 1) // utilizatorul introduce mai mult de un caracter
      {
         for(unsigned int i = 0; i < temp.size(); i++) // verificam daca exista caractere scrise cu caps lock
         {
            if(temp[i] >= 65 && temp[i] <= 90)
            {
               cout << "Ai introdus caractere cu caps lock, acestea sunt interzise, vrei sa incerci din nou?\n";
               i = temp.size();
               numar_de_control = 1; // trecem numar_de_control la 1 daca gasim caractere cu caps lock
               din_nou = getch();
               break;
            }
         }
         if(numar_de_control != 0)
         {
            continue; // resetam bucla daca este gasit
         }
         else
         {
            for(int i = 0; i < marime_vector; i++) // cautam cifrele scrise pe litere in interiorul vectorului
            {
               if(temp == numere[i])
               {
                  cout << "Ai introdus " << temp << " adica " << i << ".\n";
                  i = marime_vector;
               }
               else if(i == (marime_vector - 1)) // bucla ajunge la ultimul element si nu a gasit nici un cuvant cunoscut
               {
                  if(temp != numere[marime_vector -1])
                  {
                     cout << "Cuvantul introdus nu este o cifra scrisa cu litere.\n";
                  }
               }
 
            }
         }
 
 
      }
 
      cout << "Vrei sa mai incerci o data ?\n";
      din_nou = getch();
      system("CLS"); // e un obicei prost dar pentru utilizatori de windows momentan nu este o problema
   }while(din_nou == 'y' || din_nou == 'Y');
 
 
 
   return 0;
}

Bun acum sa luam fiecare bucata de cod in parte si sa o analizam.
char din_nou = ' ';
   const int marime_vector = 10;
   int numar_de_control = 0; //folosit pentru controlul buclelor(loop's)
   string temp; // stocheaza imput-ul utilizatorului
   vector<string> numere(marime_vector);
   numere[0] = "zero";
   numere[1] = "unu";
   numere[2] = "doi";
   numere[3] = "trei";
   numere[4] = "four";
   numere[5] = "cinci";
   numere[6] = "sase";
   numere[7] = "sapte";
   numere[8] = "opt";
   numere[9] = "noua";
Ce avem de fapt aici? Avem declarate variabilele pe care le vom folosii.

char din_nou = ' '; 
Declaram variabila "din_nou", de tip char, caruia ii asignam un caracter spatiu, este intotdeauna bine sa initializam variabilele dupa declararea lor pentru a nu avea probleme pe parcursul rularii programului.Aceasta v-a pastra un caracter de control, la sfarsitul programului utilizatorul v-a fi intrebat daca doreste sa incerce din nou, daca v-a apasa "y" sau "Y" atunci programul o va lua de la inceput, daca v-a apasa alta tasta programul se v-a inchide.



const int marime_vector = 10;
Aici creem o valoare constanta de tip int, ea nu poate fi modificata pe parcursul rularii programului. Este preferata utilizarea valorilor constante asupra "constantelor magice". Constantele magice sunt valori atribuite unor variabile , valori care insa nu se vor modifica pe parcursul rularii programului.
Sa va dau un exemplu:

vector<string> numere[10]
Valoarea 10 este o "constanta magica" daca pe parcursul rularii unui program aceasta nu se v-a modifica.


string temp = " ";
Aici creem si initializam o variabila de tip string, ce v-a contine ceea ce utilizatorul v-a introduce atunci cand este rugat.


vector<string> numere(marime_vector);
numere[0] = "zero";
numere[1] = "unu";
numere[2] = "doi";
numere[3] = "trei";
numere[4] = "four";
numere[5] = "cinci";
numere[6] = "sase";
numere[7] = "sapte";
numere[8] = "opt";
numere[9] = "noua";
Aici creem un vector de tip string, cu o marime fixa, aceasta este marime_vector = 10. Aveti un pic mai sus explicatia pentru "marime_vector". Dupa ce creem vectorul il initializam, adica ii adaugam o valoare initiala.

Pentru a nu fi necesara repornirea programului pentru fiecare incercare o sa folosim o constructie de tipul

do
{
   Cod de executat aici
}while(conditii de reexecutare)
prin folosirea "do" ne asiguram ca programul este executat cel putin o data.

while(conditii de executare)
{
 cod de executat
}
O constructie de genul "while" v-a verifica intai conditiile si abea apoi v-a rula codul, ceea ce poate duce la neexecutarea codului daca nu sunt indeplinite conditiile nici macar o data.


numar_de_control = 0; 
cout << "Acest program v-a prelula de la utilizator un input,\n";
cout << "precum '7' sau 'sapte' si v-a printa pe ecran corespondentul lui\n";
getline(cin,temp); 
Aici avem partea de intampinare si solicitarea primului input al userului. Setam variabila "numar_de_control" la 0 aici deoarece avem nevoie ca de fiecare data cand programul trece prin bucla sa putem controla executia codului cu aceasta variabila, daca nu am avea variabila aici la urmatoarea trecere prin bucla o sa avem eroiri.
folosim linia urmatoare pentru a prelua absolut tot ceea ce utilizatorul a introdus.

getline(cin,temp);
Folosim "getline" in loc de "cin" deoarece la folosirea "cin" daca utilizatorul va introduce un spatiu in input, in variabila "temp" nu ar ajunge decat ceea ce s-a introdus pana la spatiu.

In continuare intram in partea de control a executiei programului.

if(temp.size() == 1) // user enters 1 character
{
   if((int(temp[0]) &gt;= 48 &amp;&amp; int(temp[0] &lt;= 57)) || (temp[0] &gt;= 0 &amp;&amp; temp[0] &lt;= 9)) // check if it's an number
   {
      for(int i = 0; i &lt; 10; i++) // cautam numarul in vector
      {
         if(atoi(temp.c_str()) == i)
         {
            cout &lt;&lt; "Ai introdus " &lt;&lt; temp &lt;&lt; " adica " &lt;&lt; numere[i] &lt;&lt; "." &lt;&lt; endl;

         }
      }
   }
   else
   {
      cout &lt;&lt; "Nu ai introdus o cifra.\n";
   }
}
Intai verificam daca utilizatorul a introdus un caracter.
Daca s-a introdus un singur caracter v-om presupune ca utilizatorul a dorit introducerea unei cifre si v-om verifica daca intr-adevar s-a introdus o cifra si nu altceva.
verificarea marimi sirului de caractere se v-a face prin urmatorul cod

if(temp.size() == 1)
"size()" este o functie membru a obiectului "string". Ea ne v-a returna o valoare de tip "int" pe care noi o comparam cu valoarea dorita, in cazul de fata "1".
In continuare verificam daca s-a introdus un numar

if((int(temp[0]) >= 48 && int(temp[0] <= 57)) || (temp[0] >= 0 && temp[0] <= 9))
Valorile "48", "57", sunt luate din tabelul ASCI astfel verificam daca valoarea "int" a variabilei introduse este intre "48 si "57" adica intre 0 si 9, apoi verificam separat si daca ceea ce s-a introdus este de tip "int" si comparam direct cu valorile "0" - "9". Verificarea se face de 2 ori deoarece este posibil ca utilizatorul sa introduca o litera, asta fiind testat in prima parte a verificari, iar daca utilizatorul introduce o cifra, verificam in a 2-a parte a codului.


for(int i = 0; i < marime_vector; i++) // cautam numarul in vector
{
   if(atoi(temp.c_str()) == i)
   {
      cout << "Ai introdus " << temp << " adica " << numere[i] << "." << endl;

    }
}
Aici folosim o construcite de tip for.Aceasta preaia un element de control, un contorizator, sub forma unei variabile, pe baza celei variabile se verifica niste conditii, iar daca acele conditii sunt indeplinite se v-a face o actiune(cea dupa i < marime_vector in cazul nostru si anume i++), dupa care se v-a executa codul dintre acolade. Acest tip de constructie este util atunci cand cunoastem numarul de executii necesar, in cazul nostru 10(marime_vector)
Functia atoi preia un "c style string" adica un sir de caractere utilizat in limbajul de programare "C" si mostenit de "C++", sirul de caractere este tinut intr-un sir(array) de tip char. Functia returneaza o valoare de tip int pe care noi apoi o comparam cu valoarea "i".Totusi noi nu avem un "c style string" ci un string normal. Aici intervine functia c_str. Aceasta preaia un string c++ si reda un "c style string". Mai multe referinte pentru atoi si c_str aveti in linkurile puse pe numele lor. De ce comparam cu "i"? Pai tineti minte vectorul nostru "numere"? Putem afisa oricare din elemente dupa numarul lui, numerotarea incepe de la 0, primul element are 0, al 2-lea are 1, si asa mai departe. In momentul in care cifra introdusa de utilizator este egala cu "i" atunci stim care element din vectorul "numere" sa afisam.
Dupa ce gasim care este cifra noastra prin

if(atoi(temp.c_str()) == i)
afisam cifra si corespondentul ei prin

cout << "Ai introdus " << temp << " adica " << numere[i] << "." << endl;
Intotdeauna cand folosim "if" este bine sa avem si un "else", "else" este o masura de siguranta, daca nu sunt indeplinite conditiile de la "if" codul de la "else" v-a fi executat.
Aici afisam utilizatorului ca nu a introdus o cifra prin:
else
{
   cout << "Nu ai introdus o cifra.\n";
}
A doua parte a programului e ceva mai complicata fiind nevoie de mai multe verificari pentru a ne asigura ca totul este in regula.
if(temp.size() > 1) // utilizatorul introduce mai mult de un caracter
{
   for(unsigned int i = 0; i < temp.size(); i++) // verificam daca exista caractere scrise cu caps lock
   {
      if(temp[i] >= 65 && temp[i] <= 90)
      {
         cout << "Ai introdus caractere cu caps lock, acestea sunt interzise, vrei sa incerci din nou?\n";
         i = temp.size();
         numar_de_control = 1; // trecem numar_de_control la 1 daca gasim caractere cu caps lock
         din_nou = getch();
         break;
      }
   }
   if(numar_de_control != 0)
   {
      continue; // resetam bucla daca este gasit
   }
   else
   {
      for(int i = 0; i < marime_vector; i++) // cautam cifrele scrise pe litere in interiorul vectorului
      {
         if(temp == numere[i])
         {
            cout << "Ai introdus " << temp << " adica " << i << ".\n";
            i = marime_vector;
         }
         else if(i == (marime_vector - 1)) // loop reaces last item in vector and the number is not found
         {
            if(temp != numere[marime_vector -1])
            {
               cout << "Cuvantul introdus nu este o cifra scrisa cu litere.\n";
            }
         }
      }
   }
}
Mai departe.
for(unsigned int i = 0; i < temp.size(); i++) // verificam daca exista caractere scrise cu caps lock
{
   if(temp[i] >= 65 && temp[i] <= 90)
   {
      cout << "Ai introdus caractere cu caps lock, acestea sunt interzise, vrei sa incerci din nou(y sau Y pentru da, orice alta tasta pentru nu)?\n";
      i = temp.size();
      numar_de_control = 1; // trecem numar_de_control la 1 daca gasim caractere cu caps lock
      din_nou = getch();
      break;
   }
}
Folosim din nou o constructie "for" pentru a trece prin fiecare caracter din string-ul introdus de catre utilizator de data asta pentru a verifica daca utilizatorul a introdus caractere scrise cu caps lock on. Folosim 65 si 90 deoarece in tabellul ASCII 65 este prima litera cu caps lock si anume "A" si 90 este "Z". Daca este gasit un caracter cu caps lock atunci v-om intreba utilizatorul daca doreste sa incerce din nou, si v-a fi nevoit sa introduca "y" sau "Y" pentru a incerca din nou sau orice alta tasta daca nu mai doreste. Imediat dupa aceasta parte avem :
if(numar_de_control != 0)
{
   continue; // resetam bucla daca este gasit
}
Aici intra in joc "numar_de control". Daca acesta este diferit de "0" bucla o va lua de la capat datorita comenzii "continue". Daca nu am gasit nici o majuscula atunci executam a 2-a parte din cod si anume:
else
{
   for(int i = 0; i < marime_vector; i++) // cautam cifrele scrise pe litere in interiorul vectorului
   {
      if(temp == numere[i])
      {
         cout << "Ai introdus " << temp << " adica " << i << ".\n";
         i = marime_vector;
      }
      else if(i == (marime_vector - 1)) // loop reaces last item in vector and the number is not found
      {
         if(temp != numere[marime_vector -1])
         {
            cout << "Cuvantul introdus nu este o cifra scrisa cu litere.\n";
         }
      }
   }
}
Dupa cum spuneam mai sus ne folosim de "if" si "else", intai am avut error checking, acum cautam de fapt cifra introdusa pe litere si afisam ceea ce gasim. Folosim din nou un o bucla "for" pentru a trece prin fiecare element al vectorului "numere" si comparam cu ceea ce a introdus utilizatorul.
for(int i = 0; i < marime_vector; i++) // cautam cifrele scrise pe litere in interiorul vectorului
{
   if(temp == numere[i])
   {
      cout << "Ai introdus " << temp << " adica " << i << ".\n";
      i = marime_vector;
   }
   else if(i == (marime_vector - 1)) // loop reaces last item in vector and the number is not found
   {
      if(temp != numere[marime_vector -1])
      {
         cout << "Cuvantul introdus nu este o cifra scrisa cu litere.\n";
      }
   }
}
Mai devreme am spus despre "if" si "else" totusi sunt cazuri unde dorim sa verificam mai multe chestii, c++ nu are o constructie speciala pentru asta dar putem combina if si else in felul urmator
if(conditie)
{
   cod de executat;
}
else if(conditie)
{
   cod de executat;
}
else if(conditie)
{
   cod de executat;
}
.
.
.
.
else
{
   cod de executat;
}
Aici verificam daca prima conditie este indeplinita, daca nu mergem la a 2-a, la a 3-a, daca nu v-a fi indeplinita nici una din conditii atunci se va executa conditia "else". In cazul codului nostru totusi avem o mica exceptie, avem "if", "else if" dar nu mai avem "else", asta pentru ca in cazul de fata conditia de siguranta este executata in "else if" pentru ca si in cazul conditiei de siguranta trebuie sa verificam niste conditii, si anume daca am ajuns la capatul vectorului "numere". Daca utilizatorul nu a introdus un cuvant cunoscut, o cifra scrisa pe litere atunci calculatorul v-a afisa acest lucru prin:
if(temp != numere[marime_vector -1])
{
   cout << "Cuvantul introdus nu este o cifra scrisa cu litere.\n";
}
In incheiere utilizatorul este intrebat daca doreste sa ruleze programul inca o data prin:
cout << "Vrei sa mai incerci o data ?\n";
din_nou = getch();
system("CLS"); // e un obicei prost dar pentru utilizatori de windows momentan nu este o problema
Afisam utilizatorului intrebarea prin "cout" dupa care folosim functia "getch()". Aceasta functie de fapt preia un caracter introdus care nu este afisat pe ecran si returneaza valoarea int a acesteia, valoarea int este cea din tabelul ASCII. In acest moment aceasta functie este oarecum invechita si este sugerat sa folosititi functia "_getch()" efectul este acelasi pentru abmele, doar ca a 2-a este o varianta mai noua a functiei respective. Dupa ce utilizatorul da raspunsul facem curat pe ecran folosint functia "system()", aceasta preia anumiti parametri speciali, cum ar fi "CLS" dar functia aceasta primeste parametri in functie de sistemul de operare, spre exemplu pe un sistem linux, codul "system("CLS"); v-a da o eroare. Cateva referinte despre "system()" aveti aici Dupa ce am facut si curat pe ecran verificam ceea ce a introdus utilizatorul cand a fost intrebat daca doreste sa mai ruleze programul inca o data prin:
}while(din_nou == 'y' || din_nou == 'Y');
dupa care avem comanda de terminare cu succes si anume "return 0;" Si cu asta am terminat acest program. Daca aveti intrebari postatile la comentarii si va voi raspunde cat de repede pot.