<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[Suport-Programare.net- Ajutor la programare - Toate forumurile]]></title>
		<link>http://suport-programare.net/</link>
		<description><![CDATA[Suport-Programare.net- Ajutor la programare - http://suport-programare.net]]></description>
		<pubDate>Tue, 06 Jan 2009 20:59:58 -0600</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[dare_to_be_different1916]]></title>
			<link>http://suport-programare.net/showthread.php?tid=17</link>
			<pubDate>Fri, 01 Aug 2008 13:00:13 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=17</guid>
			<description><![CDATA[Salut.Ma numesc Marian.Ma semnez cu dtbd1916 de la dare_to_be_different1916.Am 22 de ani.Am cunostinte de html,css,php,mysql,flash,actionscript,photoshop,dreamweaver si pe viitor intentionez sa imi bag nasul si in javascript,illustrator si xml.Dupa cum se vede sunt pasionat de web design.Inca sunt in faza incipienta:n`am nici macar un an de cand am inceput sa studiez primul tutorial de html(de html bineinteles caci este primul cu care am inceput toti).Actualmente lucrez la propriul blog.<br />
<br />
Sunt dornic de a cunoaste si de a invata de aceea m`am si inregistrat pe acest forum.M`am inregistrat si in speranta de a intalni,interactiona si dialoga cu alti pasionati ai web designului mai experimentati decat mine care sa ma ajute atunci cand ajung intr`un impas caci pentru aceasta au fost create si forumurile:sa faciliteze schimbul de cunostinte si sa ne putem ajuta unul pe altul.]]></description>
			<content:encoded><![CDATA[Salut.Ma numesc Marian.Ma semnez cu dtbd1916 de la dare_to_be_different1916.Am 22 de ani.Am cunostinte de html,css,php,mysql,flash,actionscript,photoshop,dreamweaver si pe viitor intentionez sa imi bag nasul si in javascript,illustrator si xml.Dupa cum se vede sunt pasionat de web design.Inca sunt in faza incipienta:n`am nici macar un an de cand am inceput sa studiez primul tutorial de html(de html bineinteles caci este primul cu care am inceput toti).Actualmente lucrez la propriul blog.<br />
<br />
Sunt dornic de a cunoaste si de a invata de aceea m`am si inregistrat pe acest forum.M`am inregistrat si in speranta de a intalni,interactiona si dialoga cu alti pasionati ai web designului mai experimentati decat mine care sa ma ajute atunci cand ajung intr`un impas caci pentru aceasta au fost create si forumurile:sa faciliteze schimbul de cunostinte si sa ne putem ajuta unul pe altul.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[securitatea formularelor de autentificare]]></title>
			<link>http://suport-programare.net/showthread.php?tid=16</link>
			<pubDate>Fri, 01 Aug 2008 12:44:35 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=16</guid>
			<description><![CDATA[Am urmatorul formular de autentificare:<br />
<br />
<br />
<br />
username:<br />
<br />
password:<br />
<br />
<br />
<br />
<br />
<br />
si pagina procesare.php care imi prelucreaza datele din formular:<br />
<br />
Cod PHP:<br />
&lt;?php&nbsp;if(&#36;_POST['username']&nbsp;==&nbsp;'username`ul_meu'&nbsp;&amp;&amp;&nbsp;&#36;_POST['password']&nbsp;==&nbsp;'parola_mea'){echo'&lt;table&gt;...&lt;/table&gt;//un&nbsp;tabel&nbsp;oarecare';}else{echo&nbsp;'Nu&nbsp;esti&nbsp;autorizat&nbsp;sa&nbsp;accesezi&nbsp;aceasta&nbsp;pagina&nbsp;web!!';}?&gt;<br />
<br />
Vreau sa stiu daca mai trebuie sa adaug ceva la codul PHP ca sa nu am vulnerabilitati de securitate.Vreau sa va uitati la cod si sa imi spuneti ce buguri are.<br />
<br />
Multumesc.]]></description>
			<content:encoded><![CDATA[Am urmatorul formular de autentificare:<br />
<br />
<br />
<br />
username:<br />
<br />
password:<br />
<br />
<br />
<br />
<br />
<br />
si pagina procesare.php care imi prelucreaza datele din formular:<br />
<br />
Cod PHP:<br />
&lt;?php&nbsp;if(&#36;_POST['username']&nbsp;==&nbsp;'username`ul_meu'&nbsp;&amp;&amp;&nbsp;&#36;_POST['password']&nbsp;==&nbsp;'parola_mea'){echo'&lt;table&gt;...&lt;/table&gt;//un&nbsp;tabel&nbsp;oarecare';}else{echo&nbsp;'Nu&nbsp;esti&nbsp;autorizat&nbsp;sa&nbsp;accesezi&nbsp;aceasta&nbsp;pagina&nbsp;web!!';}?&gt;<br />
<br />
Vreau sa stiu daca mai trebuie sa adaug ceva la codul PHP ca sa nu am vulnerabilitati de securitate.Vreau sa va uitati la cod si sa imi spuneti ce buguri are.<br />
<br />
Multumesc.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[De cand programezi?]]></title>
			<link>http://suport-programare.net/showthread.php?tid=15</link>
			<pubDate>Fri, 20 Jun 2008 08:01:11 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=15</guid>
			<description><![CDATA[De cat timp te-ai apucat de programare? Cine te-a indrumat? Cine ti-a explicat prima data elementele de baza ale unui program?]]></description>
			<content:encoded><![CDATA[De cat timp te-ai apucat de programare? Cine te-a indrumat? Cine ti-a explicat prima data elementele de baza ale unui program?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Salut]]></title>
			<link>http://suport-programare.net/showthread.php?tid=14</link>
			<pubDate>Thu, 19 Jun 2008 05:14:48 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=14</guid>
			<description><![CDATA[Ma numesc Adrian si sunt din Bucuresti.<br />
Cunoscut si ca astan pe skullbox.info sau adrstan pe invatam.net ...]]></description>
			<content:encoded><![CDATA[Ma numesc Adrian si sunt din Bucuresti.<br />
Cunoscut si ca astan pe skullbox.info sau adrstan pe invatam.net ...]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[Tutorial] Accesarea unei baze de date Mysql din C]]></title>
			<link>http://suport-programare.net/showthread.php?tid=13</link>
			<pubDate>Thu, 19 Jun 2008 05:11:47 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=13</guid>
			<description><![CDATA[Notiuni introductive privind accesarea unei baze de date MYSQL din limbajul C<br />
<br />
Acest tutorial presupune ca folositi sistemul de operare Linux (desi exemplele ar trebui sa se compileze si pe Windows).<br />
Mai presupun si ca server-ul MYSQL este instalat si, de asemenea, ca libraria client (utilizata pentru<br />
a scrie programe client care sa acceseze serverul) este instalata<br />
Tutorialul se adreseaza incepatorilor.<br />
<br />
A. Pornirea si oprirea server-ului MYSQL<br />
Inainte de a accesa o baza de date MYSQL trebuie, evident, sa pornim serverul mysql.<br />
<br />
Deschideti o console si executati:<br />
<br />
%>  sudo /etc/init.d/mysql start<br />
Password: xxxxx<br />
 * Starting MySQL database server mysqld                                 [ OK ] <br />
 * Checking for corrupt, not cleanly closed and upgrade needing tables.<br />
<br />
Inlocuiti "xxxxx" cu parola de root<br />
<br />
Oprirea server-ului MYSQL:<br />
sudo /etc/init.d/mysql stop<br />
 * Stopping MySQL database server mysqld                                 [ OK ] <br />
 <br />
Verificarea daca server-ul MYSQL este pornit:<br />
%> sudo mysqladmin -p ping<br />
 Password:<br />
 Enter password: <br />
 mysqld is alive <br />
<br />
<br />
B. Api-ul client pentru MYSQL (in limbajul C)<br />
<br />
Functii importante:<br />
<br />
const char *mysql_get_client_info(void) <br />
Returneaza un string care reprezinta versiunea librariei client<br />
<br />
MYSQL *mysql_init(MYSQL *mysql)<br />
Initializeaza un obiect MYSQL ce va fi folosit ulterior pentru conexiunea la server.<br />
Daca parametrul "mysql" este NULL, atunci se aloca un nou obiect MYSQL inainte de initializare si se intoarce un pointer la el<br />
Daca parametrul "mysql" nu este NULL, atunci obiectul pasat se reinitializeaza si se intoarce un pointer la acelasi obiect<br />
<br />
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)<br />
Aceasta este functia utilizata in programul client pentru conectarea la serverul MYSQL<br />
mysql - pointer la un obiect MYSQL, obtinut in urma unui apel al functiei mysql_init()<br />
host - un sir care contine adresa server-ului (hostname sau IP). Daca host contine sirul "localhost" sau este NULL, se presupune ca programul client si server-ul se afla pe aceeasi masina<br />
user - un sir de caractere care contine username-ul folosit pentru conectarea la server. Daca este NULL sau contine "", se presupune ca user-ul<br />
este cel curent<br />
passwd - parola folosita de "user" pentru conectarea la server<br />
db - numele bazei de date care va fi folosita in mod implicit<br />
port - daca nu este 0, specifica portul pe care clientul va incerca sa il foloseasca pentru a se conecta la server<br />
unix_socket - daca nu este NULL, specifica socket-ul (unix domain) sau pipe-ul folosit pentru comunicarea intre server si client<br />
client_flag - folosit pentru a seta diverse flag-uri, de exemplu daca pachetele transferate intre client si server vor fi comprimate (folosind Zlib), sau daca se foloseste SSL<br />
Functia intoarce un pointer catre un obiect MYSQL care va fi folosit ca un "handle" pentru comunicatia viitoare intre client si server. <br />
Daca functia esueaza se intoarce NULL<br />
<br />
int mysql_query(MYSQL *mysql, const char *stmt_str)<br />
Functia este folosita de catre client pentru interogarea bazei de date<br />
mysql - un obiect MYSQL valid obtinut in urma unui apel mysql_real_connect care a reusit<br />
stmt_str - un string care reprezinta interogarea SQL ce va fi transmisa server-ului pentru a fi executata pe o baza de date. Se pot specifica mai multe "statement-uri" SQL separate prin caracterul ';'<br />
Daca interogarea a reusit se intoarce 0, altfel se intoarce o valoare diferita de 0<br />
<br />
MYSQL_RES *mysql_store_result(MYSQL *mysql)<br />
Dupa apelul mysql_query() sau mysql_real_query() trebuie apelata functia mysql_store_result(). Aceasta intoarce un pointer la un obiect MYSQL_RES, care va fi folosit pentru extragerea rezultatului interogarii<br />
Se intoarce NULL daca functia esueaza<br />
<br />
unsigned int mysql_num_fields(MYSQL_RES *result)<br />
Returneaza numarul de coloane returnat in urma unui apel mysql_store_result()<br />
result - este un pointer catre un obiect MYSQL_RES, intors de exemplu de catre functia mysql_store_result()<br />
<br />
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)<br />
Extrage urmatoarea linie din set-ul resultat in urma executiei unei interogari SQL<br />
result - un pointer la un obiect MYSQL_RES obtinut de exemplu in urma executiei unui apel mysql_store_result()<br />
Functie intoarce o structura de tip MYSQL_ROW folosita pentru a accesa urmatoare linie a setului. Se intoarce NULL daca am ajuns la sfarsitul setului<br />
<br />
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)<br />
Functia este utilizata pentru a obtine informatii despre o coloana apartinant unui set rezultat in urma executiei unei interogari SQL<br />
result - un pointer la un obiect MYSQL_RES obtinut de exemplu in urma executiei unui apel mysql_store_result()<br />
Functie intoarce o structura de tip MYSQL_FIELD folosita pentru a accesa informatii despre o coloana din set. Functia intoarce NULL cand s-au parcurs deja toate coloanele setului<br />
<br />
void mysql_free_result(MYSQL_RES *result)<br />
Dezaloca resursele asociate unui obiect MYSQL_RES<br />
result - un pointer la un obiect MYSQL_RES obtinut de exemplu in urma executiei unui apel mysql_store_result()<br />
<br />
void mysql_close(MYSQL *mysql)<br />
Inchide conexiunea catre server<br />
mysql - un obiect de tip MYSQL folosit pentru comunicatia intre client si server (obtinut, de exemplu, in urma unui apel mysql_real_connect())<br />
<br />
Bun, aceste sunt functiile principale ale API-ului. Sa vedem cum sunt folosite in programe practice.<br />
<br />
C) Exemple de programe client<br />
Asigurati-va ca sever-ul MYSQL este pornit inainte sa executati programele demonstrative ce vor urma<br />
<br />
Programele client trebuie sa include urmatoarele header-e: "my_global.h" si "mysql.h"<br />
<br />
C.1) Aflarea versiunii clientului<br />
<br />
Cod:<br />
/* versiune_client.c */<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "Versiunea clientului este %s&#92;n", mysql_get_client_info());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii<br />
<br />
mysql_get_client_info()<br />
->returneaza un string ce indica versiunea librariei client<br />
<br />
Compilare:<br />
%> gcc versiune_client.c -o versiune_client `mysql_config --cflags --libs`<br />
<br />
Executie:<br />
%> chmod +x versiune_client<br />
%> ./versiune_client<br />
Versiunea clientului este 5.0.38<br />
<br />
C.2) Crearea unei baze de date<br />
Vom crea o baza de date pe care o vom denumi "info_studenti". Ea va fi folosita pentru a tine informatii despre studentii participanti la un curs<br />
<br />
Cod:<br />
/* creare_bd.c */<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL *conn;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn = mysql_init(NULL);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (conn == NULL) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr, "Eroare %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_FAILURE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (mysql_real_connect(conn, "localhost", "username", "parola", NULL, 0, NULL, 0) == NULL) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la conexiune catre server %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (mysql_query(conn, "create database info_studenti") != 0) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"Error %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "Am create baza de date info_studenti&#92;n");<br />
&nbsp;&nbsp;&nbsp;&nbsp; mysql_close(conn);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii:<br />
<br />
conn = mysql_init(NULL); <br />
-> initializez conn pentru conexiunea ulterioara catre baza de date<br />
<br />
if (conn == NULL) <br />
{<br />
    fprintf(stderr, "Eroare %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
    return EXIT_FAILURE;<br />
}<br />
-> verific daca initializarea a reusit<br />
<br />
if (mysql_real_connect(conn, "localhost", "username", "parola", NULL, 0, NULL, 0) == NULL) <br />
{<br />
    fprintf(stderr, "Eroare la conexiune catres erver %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
    return EXIT_FAILURE;<br />
}<br />
-> Ma conectez la server-ul MYSQL. In cazul meu, server-ul si clientul se afla pe aceeasi masina (am specificat localhost)<br />
Inlocuieste "username" si "parola" cu username-ul si parola ta<br />
<br />
 if (mysql_query(conn, "create database info_studenti") != 0) <br />
 {<br />
      fprintf(stderr,"Error %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
      return EXIT_FAILURE;<br />
 }<br />
 -> Creez baza de date prin executia urmatoarei interogari SQL: "create database info_studenti"<br />
<br />
 mysql_close(conn);<br />
-> Inchide conexiunea catre server<br />
 <br />
 Compilare:<br />
 %> gcc creare_bd.c -o creare_bd `mysql_config --cflags --libs`<br />
 <br />
 Executie:<br />
 %> chmod +x creare_bd<br />
 ./creare_bd <br />
 Am create baza de date info_studenti<br />
<br />
 Nota:<br />
 Daca vom mai incerca sa executam inca o data programul, vom obtine urmatoarea eroare:<br />
 %> ./creare_bd <br />
 Error 1007: Can't create database 'info_studenti'; database exists <br />
 Aceasta deoarece putem sa creem baza de date o singura data<br />
 <br />
 Hai sa vedem acum ca baza de date chiar a fost creata.<br />
 <br />
 Putem sa folosim utilitarul mysql pentru a inspecta bazele de date existente. <br />
Executa din consola:<br />
 <br />
 %> mysql -u root -p<br />
 <br />
 apoi introdu parola<br />
 De la promptul mysql> executa:<br />
 mysql> SHOW DATABASES;<br />
 <br />
Exemplu:<br />
<br />
mysql -u root -p<br />
Enter password: -> introduceti parola pentru user-ul root<br />
Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
Your MySQL connection id is 15<br />
Server version: 5.0.38-Ubuntu_0ubuntu1.4-log Ubuntu 7.04 distribution<br />
<br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br />
<br />
mysql> SHOW DATABASES;<br />
+--------------------+<br />
| Database           |<br />
+--------------------+<br />
| information_schema | <br />
| info_studenti      | <br />
| mysql              | <br />
| testdb11           | <br />
+--------------------+<br />
4 rows in set (0.00 sec)#include <br />
<br />
mysql> quit <br />
Bye<br />
<br />
Nota: Nu uita caracterul ';' dupa ce executi SHOW DATABASES;<br />
<br />
Bun, am creat o baza de date. Acum e cazul sa si populam acea baza de date cu un tabel si sa introducem niste date in acel tabel.<br />
<br />
C3) Creearea unui tabel si introducerea de inregistrari<br />
Vom crea un tabel care se numeste "studenti", in baza de date "info_studenti". Tabelul va contine urmatoarele date despre studenti:<br />
- ID<br />
- Nume<br />
- Medie<br />
<br />
Tabelul va fi creat folosind urmatoarea interogare SQL:<br />
CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double)"<br />
<br />
Tabelul va avea un intreg identificat prin "id" ca cheie primara de tip auto_increment. Aceasta inseamna ca valoarea campului "id" va fi incrementata automat de fiecare data cand in tabel for fi introduse inregistrari.<br />
Campul "nume" va fi folosit pentru a tine numele studentului. <br />
Campul "media" e de tip double si va contine media anuala a studentului<br />
<br />
Codul este urmatorul:<br />
<br />
Cod:<br />
/*inserare_date.c*/<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main()<br />
{<br />
<br />
&nbsp;&nbsp;MYSQL *conn;<br />
<br />
&nbsp;&nbsp;conn = mysql_init(NULL);<br />
&nbsp;&nbsp;if (conn == NULL) <br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la initializare %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;if (mysql_real_connect(conn, "localhost", "username", "parola", "info_studenti", 0, NULL, 0) == NULL)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la conexiune catre server %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;if (mysql_query(conn, "CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double)") != 0)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Nu pot crea tabelul &#92;"studenti&#92;" in baza de date &#92;"info_studenti&#92;"");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Ion', 7.77)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Gheorghe', 8)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Maria', 9.50)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Vasile', 10)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Dumitru', 5)");<br />
<br />
&nbsp;&nbsp;mysql_close(conn);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii:<br />
<br />
if (mysql_real_connect(conn, "localhost", "username", "parola", "info_studenti", 0, NULL, 0) == NULL)<br />
{<br />
     fprintf(stderr, "Eroare la conexiune catre server %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
     return EXIT_FAILURE;<br />
}<br />
-> Ma conectez la server-ul MYSQL. In cazul meu, server-ul si clientul se afla pe aceeasi masina (am specificat localhost)<br />
Inlocuieste "username" si "parola" cu username-ul si parola ta. In apel se specifica ca baza de date implicita pe care se vor face urmatoarele operatii va fi "info_studenti"<br />
<br />
if (mysql_query(conn, "CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double)") != 0)<br />
{<br />
    fprintf(stderr, "Nu pot crea tabelul \"studenti\" in baza de date \"info_studenti\"");<br />
    return EXIT_FAILURE;<br />
}<br />
-> Creez tabelul "studenti", asa cum am explicat inainte<br />
<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Ion', 7.77)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Gheorghe', 8)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Maria', 9.50)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Vasile', 10)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Dumitru', 5)");<br />
-> Inserez inregistrari in tabelul "studenti" nou creat<br />
<br />
Compilare:<br />
%> gcc inserare_date.c -o inserare_date `mysql_config --cflags --libs`<br />
<br />
Executie:<br />
%> chmod +x inserare_date<br />
%> ./inserare_date<br />
<br />
OK, hai sa vedem acum ca intr-adevar am creat tabelul si am adaugat inregistrari in el. Ca de obicei, folosim utilitarul mysql<br />
<br />
%> mysql -u root -p<br />
Enter password: -> introduceti parola pentru user-ul root<br />
Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
Your MySQL connection id is 29<br />
Server version: 5.0.38-Ubuntu_0ubuntu1.4-log Ubuntu 7.04 distribution<br />
<br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br />
<br />
mysql> USE info_studenti;<br />
Reading table information for completion of table and column names<br />
You can turn off this feature to get a quicker startup with -A<br />
<br />
Database changed<br />
mysql> SHOW TABLES;<br />
+-------------------------+<br />
| Tables_in_info_studenti |<br />
+-------------------------+<br />
| studenti                | <br />
+-------------------------+<br />
1 row in set (0.00 sec)<br />
<br />
mysql> SELECT * FROM studenti;<br />
+----+----------+-------+<br />
| id | nume     | media |<br />
+----+----------+-------+<br />
|  1 | Ion      |  7.77 | <br />
|  2 | Gheorghe |     8 | <br />
|  3 | Maria    |   9.5 | <br />
|  4 | Vasile   |    10 | <br />
|  5 | Dumitru  |     5 | <br />
+----+----------+-------+<br />
5 rows in set (0.00 sec)<br />
<br />
mysql> quit<br />
Bye<br />
<br />
Explicatii:<br />
USE info_studenti; -> selecteaza baza de date pentru care vrem sa obtinem informatii<br />
SHOW TABLES; -> afiseaza toate tabelele continute in baza de date selectata<br />
SELECT * FROM studenti; -> afiseaza toate inregistrarile continute in tabelul "studenti"<br />
<br />
Bun, am invatat cum se creeaza si cum se populeaza un tabel. Hai sa vedem cum se extrag inregistrarile din tabele.<br />
<br />
C4) Extragerea de inregistrari dintr-un tabel<br />
Pana acum am executat statement-uri SQL care nu returnau nici un set rezultat (result-set).<br />
In cazul anumitor interogari (de exmplu SELECT) vom avea set-uri rezultate.<br />
In programul urmator vom extrage datele introduse in tabelul "studenti" si vom afisa si toate coloanele asociate setului rezultat.<br />
<br />
Cod:<br />
<br />
Cod:<br />
/*extragere_date.c */<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main(int argc, char **argv)<br />
{<br />
&nbsp;&nbsp;MYSQL *conn;<br />
&nbsp;&nbsp;MYSQL_RES *result;<br />
&nbsp;&nbsp;MYSQL_ROW row;<br />
&nbsp;&nbsp;int num_fields;<br />
&nbsp;&nbsp;MYSQL_FIELD *field;<br />
&nbsp;&nbsp;int i;<br />
<br />
&nbsp;&nbsp;conn = mysql_init(NULL);<br />
&nbsp;&nbsp;if (conn == NULL) <br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la initializare %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;if (mysql_real_connect(conn, "localhost", "username", "parola", "info_studenti", 0, NULL, 0) == NULL)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la conexiune catre server %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;mysql_query(conn, "SELECT * FROM studenti");<br />
&nbsp;&nbsp;result = mysql_store_result(conn);<br />
<br />
&nbsp;&nbsp;if (result == NULL)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "Nu am gasit nici o inregistrare &#92;n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;num_fields = mysql_num_fields(result);<br />
<br />
&nbsp;&nbsp;while ((row = mysql_fetch_row(result)))<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; num_fields; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (i == 0) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(field = mysql_fetch_field(result)) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s ", field-&gt;name);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("&#92;n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s ", row[i] ? row[i] : "NULL");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;printf("&#92;n");<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;mysql_free_result(result);<br />
&nbsp;&nbsp;mysql_close(conn);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii:<br />
<br />
mysql_query(conn, "SELECT * FROM studenti");<br />
-> executam urmatoarea interogare pentru a obtine toate inregistrarile din tabelul "studenti": SELECT * FROM studenti<br />
<br />
result = mysql_store_result(conn);<br />
-> apelam mysql_store_result() pentru a "stoca" rezultatul interogarii<br />
<br />
num_fields = mysql_num_fields(result);<br />
-> num_fields va contine numarul de coloane asociat setului "res"<br />
<br />
while ((row = mysql_fetch_row(result)))<br />
{<br />
   ....<br />
}<br />
-> parcurgem setul rezultat in urma interogarii line cu linie<br />
<br />
for (i = 0; i < num_fields; i++)<br />
{ <br />
   ...<br />
}<br />
-> pentru fiecare linie a setului parcurgem fiecare coloana<br />
<br />
if (i == 0) <br />
{<br />
    while(field = mysql_fetch_field(result)) <br />
    {<br />
        printf("%s ", field->name);<br />
    }<br />
    printf("\n");<br />
} <br />
-> inainte de a afisa prima linie a setului, afisam numele tuturor coloanelor<br />
<br />
printf("%s ", row ? row[i] : "NULL");<br />
-> [i]afisam linia curenta a setului apoi continuam iteratia pana cand parcurgem toate liniile setului<br />
<br />
Compilare:<br />
%> gcc extragere_date.c -o extragere_date `mysql_config --cflags --libs`<br />
<br />
Executie:<br />
%> chmod +x extragere_date<br />
%> ./extragere_date <br />
id nume media <br />
1 Ion 7.77 <br />
2 Gheorghe 8 <br />
3 Maria 9.5 <br />
4 Vasile 10 <br />
5 Dumitru 5<br />
<br />
In continuare prezint o serie de comenzi utile ce pot fi incercate atat utilizand un utilitar gen mysql sau din cod, programatic, folosind exemplele de mai sus:<br />
<br />
SHOW DATABASES; -> afiseaza totate bazele de date aflate pe server-ul MYSQL<br />
CREATE DATABASE  baza_de_date; -> creeaza o noua baza de date avand numele baza_de_date<br />
USE baza_date; -> selecteaza baza de date cu numele baza_de_date. Toate operatiile ulterioare se vor face pe aceasta baza de date (pana cand bineinteles, selectam alta)<br />
SHOW TABLES; -> afiseaza numele tuturor tabelelor bazei de date selectate curent<br />
SHOW COLUMNS FROM nume_tabel; ->ofera informatii despre coloanele tabelului nume_tabe <br />
DROP_TABLE nume_tabel; -> sterge un tabel numit nume_tabel din baza de date curent selectata<br />
DROP_DATABASE nume_database; -> sterge baza de date numita nume_database<br />
<br />
Exista multe alte comenzi, dar va trebui sa cititi help-ul pentru a le afla.<br />
<br />
In continuare se prezinta un exemplu de utilizare al comenzilor invatate folosind utilitarul mysql:<br />
<br />
 %> mysql -u root -p<br />
Enter password: <br />
Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
Your MySQL connection id is 43<br />
Server version: 5.0.38-Ubuntu_0ubuntu1.4-log Ubuntu 7.04 distribution<br />
<br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br />
<br />
mysql> SHOW DATABASES;<br />
+--------------------+<br />
| Database           |<br />
+--------------------+<br />
| information_schema | <br />
| mysql              | <br />
| testdb11           | <br />
+--------------------+<br />
3 rows in set (0.00 sec)<br />
<br />
mysql> CREATE DATABASE  baza_de_date;<br />
Query OK, 1 row affected (0.00 sec)<br />
<br />
mysql> USE baza_de_date;<br />
Database changed<br />
<br />
mysql> SHOW TABLES;<br />
Empty set (0.00 sec)<br />
<br />
mysql> CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double);<br />
Query OK, 0 rows affected (0.01 sec)<br />
<br />
mysql> SHOW TABLES;<br />
+------------------------+<br />
| Tables_in_baza_de_date |<br />
+------------------------+<br />
| studenti               | <br />
+------------------------+<br />
1 row in set (0.00 sec)<br />
<br />
mysql> SHOW COLUMNS FROM studenti;<br />
+-------+-------------+------+-----+---------+----------------+<br />
| Field | Type        | Null | Key | Default | Extra          |<br />
+-------+-------------+------+-----+---------+----------------+<br />
| id    | int(11)     | NO   | PRI | NULL    | auto_increment | <br />
| nume  | varchar(20) | YES  |     | NULL    |                | <br />
| media | double      | YES  |     | NULL    |                | <br />
+-------+-------------+------+-----+---------+----------------+<br />
3 rows in set (0.00 sec)<br />
<br />
mysql> SELECT * FROM studenti;<br />
Empty set (0.00 sec)<br />
<br />
mysql> INSERT INTO studenti(nume, media) VALUES('Ion', 7.77);<br />
Query OK, 1 row affected (0.00 sec)<br />
<br />
mysql> SELECT * FROM studenti;<br />
+----+------+-------+<br />
| id | nume | media |<br />
+----+------+-------+<br />
|  1 | Ion  |  7.77 | <br />
+----+------+-------+<br />
1 row in set (0.00 sec)<br />
<br />
mysql> DROP TABLE studenti;<br />
Query OK, 0 rows affected (0.01 sec)<br />
<br />
mysql> SHOW TABLES;<br />
Empty set (0.00 sec)<br />
<br />
mysql> DROP DATABASE baza_de_date;<br />
Query OK, 0 rows affected (0.00 sec)<br />
<br />
mysql> SHOW DATABASES;<br />
+--------------------+<br />
| Database           |<br />
+--------------------+<br />
| information_schema | <br />
| mysql              | <br />
| testdb11           | <br />
+--------------------+<br />
3 rows in set (0.00 sec)<br />
<br />
mysql> quit<br />
Bye<br />
<br />
Tutorialul a fost postat initial pe: http://www.skullbox.info/board/accesarea...t4493.html]]></description>
			<content:encoded><![CDATA[Notiuni introductive privind accesarea unei baze de date MYSQL din limbajul C<br />
<br />
Acest tutorial presupune ca folositi sistemul de operare Linux (desi exemplele ar trebui sa se compileze si pe Windows).<br />
Mai presupun si ca server-ul MYSQL este instalat si, de asemenea, ca libraria client (utilizata pentru<br />
a scrie programe client care sa acceseze serverul) este instalata<br />
Tutorialul se adreseaza incepatorilor.<br />
<br />
A. Pornirea si oprirea server-ului MYSQL<br />
Inainte de a accesa o baza de date MYSQL trebuie, evident, sa pornim serverul mysql.<br />
<br />
Deschideti o console si executati:<br />
<br />
%>  sudo /etc/init.d/mysql start<br />
Password: xxxxx<br />
 * Starting MySQL database server mysqld                                 [ OK ] <br />
 * Checking for corrupt, not cleanly closed and upgrade needing tables.<br />
<br />
Inlocuiti "xxxxx" cu parola de root<br />
<br />
Oprirea server-ului MYSQL:<br />
sudo /etc/init.d/mysql stop<br />
 * Stopping MySQL database server mysqld                                 [ OK ] <br />
 <br />
Verificarea daca server-ul MYSQL este pornit:<br />
%> sudo mysqladmin -p ping<br />
 Password:<br />
 Enter password: <br />
 mysqld is alive <br />
<br />
<br />
B. Api-ul client pentru MYSQL (in limbajul C)<br />
<br />
Functii importante:<br />
<br />
const char *mysql_get_client_info(void) <br />
Returneaza un string care reprezinta versiunea librariei client<br />
<br />
MYSQL *mysql_init(MYSQL *mysql)<br />
Initializeaza un obiect MYSQL ce va fi folosit ulterior pentru conexiunea la server.<br />
Daca parametrul "mysql" este NULL, atunci se aloca un nou obiect MYSQL inainte de initializare si se intoarce un pointer la el<br />
Daca parametrul "mysql" nu este NULL, atunci obiectul pasat se reinitializeaza si se intoarce un pointer la acelasi obiect<br />
<br />
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)<br />
Aceasta este functia utilizata in programul client pentru conectarea la serverul MYSQL<br />
mysql - pointer la un obiect MYSQL, obtinut in urma unui apel al functiei mysql_init()<br />
host - un sir care contine adresa server-ului (hostname sau IP). Daca host contine sirul "localhost" sau este NULL, se presupune ca programul client si server-ul se afla pe aceeasi masina<br />
user - un sir de caractere care contine username-ul folosit pentru conectarea la server. Daca este NULL sau contine "", se presupune ca user-ul<br />
este cel curent<br />
passwd - parola folosita de "user" pentru conectarea la server<br />
db - numele bazei de date care va fi folosita in mod implicit<br />
port - daca nu este 0, specifica portul pe care clientul va incerca sa il foloseasca pentru a se conecta la server<br />
unix_socket - daca nu este NULL, specifica socket-ul (unix domain) sau pipe-ul folosit pentru comunicarea intre server si client<br />
client_flag - folosit pentru a seta diverse flag-uri, de exemplu daca pachetele transferate intre client si server vor fi comprimate (folosind Zlib), sau daca se foloseste SSL<br />
Functia intoarce un pointer catre un obiect MYSQL care va fi folosit ca un "handle" pentru comunicatia viitoare intre client si server. <br />
Daca functia esueaza se intoarce NULL<br />
<br />
int mysql_query(MYSQL *mysql, const char *stmt_str)<br />
Functia este folosita de catre client pentru interogarea bazei de date<br />
mysql - un obiect MYSQL valid obtinut in urma unui apel mysql_real_connect care a reusit<br />
stmt_str - un string care reprezinta interogarea SQL ce va fi transmisa server-ului pentru a fi executata pe o baza de date. Se pot specifica mai multe "statement-uri" SQL separate prin caracterul ';'<br />
Daca interogarea a reusit se intoarce 0, altfel se intoarce o valoare diferita de 0<br />
<br />
MYSQL_RES *mysql_store_result(MYSQL *mysql)<br />
Dupa apelul mysql_query() sau mysql_real_query() trebuie apelata functia mysql_store_result(). Aceasta intoarce un pointer la un obiect MYSQL_RES, care va fi folosit pentru extragerea rezultatului interogarii<br />
Se intoarce NULL daca functia esueaza<br />
<br />
unsigned int mysql_num_fields(MYSQL_RES *result)<br />
Returneaza numarul de coloane returnat in urma unui apel mysql_store_result()<br />
result - este un pointer catre un obiect MYSQL_RES, intors de exemplu de catre functia mysql_store_result()<br />
<br />
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)<br />
Extrage urmatoarea linie din set-ul resultat in urma executiei unei interogari SQL<br />
result - un pointer la un obiect MYSQL_RES obtinut de exemplu in urma executiei unui apel mysql_store_result()<br />
Functie intoarce o structura de tip MYSQL_ROW folosita pentru a accesa urmatoare linie a setului. Se intoarce NULL daca am ajuns la sfarsitul setului<br />
<br />
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)<br />
Functia este utilizata pentru a obtine informatii despre o coloana apartinant unui set rezultat in urma executiei unei interogari SQL<br />
result - un pointer la un obiect MYSQL_RES obtinut de exemplu in urma executiei unui apel mysql_store_result()<br />
Functie intoarce o structura de tip MYSQL_FIELD folosita pentru a accesa informatii despre o coloana din set. Functia intoarce NULL cand s-au parcurs deja toate coloanele setului<br />
<br />
void mysql_free_result(MYSQL_RES *result)<br />
Dezaloca resursele asociate unui obiect MYSQL_RES<br />
result - un pointer la un obiect MYSQL_RES obtinut de exemplu in urma executiei unui apel mysql_store_result()<br />
<br />
void mysql_close(MYSQL *mysql)<br />
Inchide conexiunea catre server<br />
mysql - un obiect de tip MYSQL folosit pentru comunicatia intre client si server (obtinut, de exemplu, in urma unui apel mysql_real_connect())<br />
<br />
Bun, aceste sunt functiile principale ale API-ului. Sa vedem cum sunt folosite in programe practice.<br />
<br />
C) Exemple de programe client<br />
Asigurati-va ca sever-ul MYSQL este pornit inainte sa executati programele demonstrative ce vor urma<br />
<br />
Programele client trebuie sa include urmatoarele header-e: "my_global.h" si "mysql.h"<br />
<br />
C.1) Aflarea versiunii clientului<br />
<br />
Cod:<br />
/* versiune_client.c */<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "Versiunea clientului este %s&#92;n", mysql_get_client_info());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii<br />
<br />
mysql_get_client_info()<br />
->returneaza un string ce indica versiunea librariei client<br />
<br />
Compilare:<br />
%> gcc versiune_client.c -o versiune_client `mysql_config --cflags --libs`<br />
<br />
Executie:<br />
%> chmod +x versiune_client<br />
%> ./versiune_client<br />
Versiunea clientului este 5.0.38<br />
<br />
C.2) Crearea unei baze de date<br />
Vom crea o baza de date pe care o vom denumi "info_studenti". Ea va fi folosita pentru a tine informatii despre studentii participanti la un curs<br />
<br />
Cod:<br />
/* creare_bd.c */<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL *conn;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn = mysql_init(NULL);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (conn == NULL) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr, "Eroare %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_FAILURE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (mysql_real_connect(conn, "localhost", "username", "parola", NULL, 0, NULL, 0) == NULL) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la conexiune catre server %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (mysql_query(conn, "create database info_studenti") != 0) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"Error %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "Am create baza de date info_studenti&#92;n");<br />
&nbsp;&nbsp;&nbsp;&nbsp; mysql_close(conn);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii:<br />
<br />
conn = mysql_init(NULL); <br />
-> initializez conn pentru conexiunea ulterioara catre baza de date<br />
<br />
if (conn == NULL) <br />
{<br />
    fprintf(stderr, "Eroare %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
    return EXIT_FAILURE;<br />
}<br />
-> verific daca initializarea a reusit<br />
<br />
if (mysql_real_connect(conn, "localhost", "username", "parola", NULL, 0, NULL, 0) == NULL) <br />
{<br />
    fprintf(stderr, "Eroare la conexiune catres erver %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
    return EXIT_FAILURE;<br />
}<br />
-> Ma conectez la server-ul MYSQL. In cazul meu, server-ul si clientul se afla pe aceeasi masina (am specificat localhost)<br />
Inlocuieste "username" si "parola" cu username-ul si parola ta<br />
<br />
 if (mysql_query(conn, "create database info_studenti") != 0) <br />
 {<br />
      fprintf(stderr,"Error %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
      return EXIT_FAILURE;<br />
 }<br />
 -> Creez baza de date prin executia urmatoarei interogari SQL: "create database info_studenti"<br />
<br />
 mysql_close(conn);<br />
-> Inchide conexiunea catre server<br />
 <br />
 Compilare:<br />
 %> gcc creare_bd.c -o creare_bd `mysql_config --cflags --libs`<br />
 <br />
 Executie:<br />
 %> chmod +x creare_bd<br />
 ./creare_bd <br />
 Am create baza de date info_studenti<br />
<br />
 Nota:<br />
 Daca vom mai incerca sa executam inca o data programul, vom obtine urmatoarea eroare:<br />
 %> ./creare_bd <br />
 Error 1007: Can't create database 'info_studenti'; database exists <br />
 Aceasta deoarece putem sa creem baza de date o singura data<br />
 <br />
 Hai sa vedem acum ca baza de date chiar a fost creata.<br />
 <br />
 Putem sa folosim utilitarul mysql pentru a inspecta bazele de date existente. <br />
Executa din consola:<br />
 <br />
 %> mysql -u root -p<br />
 <br />
 apoi introdu parola<br />
 De la promptul mysql> executa:<br />
 mysql> SHOW DATABASES;<br />
 <br />
Exemplu:<br />
<br />
mysql -u root -p<br />
Enter password: -> introduceti parola pentru user-ul root<br />
Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
Your MySQL connection id is 15<br />
Server version: 5.0.38-Ubuntu_0ubuntu1.4-log Ubuntu 7.04 distribution<br />
<br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br />
<br />
mysql> SHOW DATABASES;<br />
+--------------------+<br />
| Database           |<br />
+--------------------+<br />
| information_schema | <br />
| info_studenti      | <br />
| mysql              | <br />
| testdb11           | <br />
+--------------------+<br />
4 rows in set (0.00 sec)#include <br />
<br />
mysql> quit <br />
Bye<br />
<br />
Nota: Nu uita caracterul ';' dupa ce executi SHOW DATABASES;<br />
<br />
Bun, am creat o baza de date. Acum e cazul sa si populam acea baza de date cu un tabel si sa introducem niste date in acel tabel.<br />
<br />
C3) Creearea unui tabel si introducerea de inregistrari<br />
Vom crea un tabel care se numeste "studenti", in baza de date "info_studenti". Tabelul va contine urmatoarele date despre studenti:<br />
- ID<br />
- Nume<br />
- Medie<br />
<br />
Tabelul va fi creat folosind urmatoarea interogare SQL:<br />
CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double)"<br />
<br />
Tabelul va avea un intreg identificat prin "id" ca cheie primara de tip auto_increment. Aceasta inseamna ca valoarea campului "id" va fi incrementata automat de fiecare data cand in tabel for fi introduse inregistrari.<br />
Campul "nume" va fi folosit pentru a tine numele studentului. <br />
Campul "media" e de tip double si va contine media anuala a studentului<br />
<br />
Codul este urmatorul:<br />
<br />
Cod:<br />
/*inserare_date.c*/<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main()<br />
{<br />
<br />
&nbsp;&nbsp;MYSQL *conn;<br />
<br />
&nbsp;&nbsp;conn = mysql_init(NULL);<br />
&nbsp;&nbsp;if (conn == NULL) <br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la initializare %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;if (mysql_real_connect(conn, "localhost", "username", "parola", "info_studenti", 0, NULL, 0) == NULL)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la conexiune catre server %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;if (mysql_query(conn, "CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double)") != 0)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Nu pot crea tabelul &#92;"studenti&#92;" in baza de date &#92;"info_studenti&#92;"");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Ion', 7.77)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Gheorghe', 8)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Maria', 9.50)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Vasile', 10)");<br />
&nbsp;&nbsp;mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Dumitru', 5)");<br />
<br />
&nbsp;&nbsp;mysql_close(conn);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii:<br />
<br />
if (mysql_real_connect(conn, "localhost", "username", "parola", "info_studenti", 0, NULL, 0) == NULL)<br />
{<br />
     fprintf(stderr, "Eroare la conexiune catre server %u: %s\n", mysql_errno(conn), mysql_error(conn));<br />
     return EXIT_FAILURE;<br />
}<br />
-> Ma conectez la server-ul MYSQL. In cazul meu, server-ul si clientul se afla pe aceeasi masina (am specificat localhost)<br />
Inlocuieste "username" si "parola" cu username-ul si parola ta. In apel se specifica ca baza de date implicita pe care se vor face urmatoarele operatii va fi "info_studenti"<br />
<br />
if (mysql_query(conn, "CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double)") != 0)<br />
{<br />
    fprintf(stderr, "Nu pot crea tabelul \"studenti\" in baza de date \"info_studenti\"");<br />
    return EXIT_FAILURE;<br />
}<br />
-> Creez tabelul "studenti", asa cum am explicat inainte<br />
<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Ion', 7.77)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Gheorghe', 8)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Maria', 9.50)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Vasile', 10)");<br />
 mysql_query(conn, "INSERT INTO studenti(nume, media) VALUES('Dumitru', 5)");<br />
-> Inserez inregistrari in tabelul "studenti" nou creat<br />
<br />
Compilare:<br />
%> gcc inserare_date.c -o inserare_date `mysql_config --cflags --libs`<br />
<br />
Executie:<br />
%> chmod +x inserare_date<br />
%> ./inserare_date<br />
<br />
OK, hai sa vedem acum ca intr-adevar am creat tabelul si am adaugat inregistrari in el. Ca de obicei, folosim utilitarul mysql<br />
<br />
%> mysql -u root -p<br />
Enter password: -> introduceti parola pentru user-ul root<br />
Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
Your MySQL connection id is 29<br />
Server version: 5.0.38-Ubuntu_0ubuntu1.4-log Ubuntu 7.04 distribution<br />
<br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br />
<br />
mysql> USE info_studenti;<br />
Reading table information for completion of table and column names<br />
You can turn off this feature to get a quicker startup with -A<br />
<br />
Database changed<br />
mysql> SHOW TABLES;<br />
+-------------------------+<br />
| Tables_in_info_studenti |<br />
+-------------------------+<br />
| studenti                | <br />
+-------------------------+<br />
1 row in set (0.00 sec)<br />
<br />
mysql> SELECT * FROM studenti;<br />
+----+----------+-------+<br />
| id | nume     | media |<br />
+----+----------+-------+<br />
|  1 | Ion      |  7.77 | <br />
|  2 | Gheorghe |     8 | <br />
|  3 | Maria    |   9.5 | <br />
|  4 | Vasile   |    10 | <br />
|  5 | Dumitru  |     5 | <br />
+----+----------+-------+<br />
5 rows in set (0.00 sec)<br />
<br />
mysql> quit<br />
Bye<br />
<br />
Explicatii:<br />
USE info_studenti; -> selecteaza baza de date pentru care vrem sa obtinem informatii<br />
SHOW TABLES; -> afiseaza toate tabelele continute in baza de date selectata<br />
SELECT * FROM studenti; -> afiseaza toate inregistrarile continute in tabelul "studenti"<br />
<br />
Bun, am invatat cum se creeaza si cum se populeaza un tabel. Hai sa vedem cum se extrag inregistrarile din tabele.<br />
<br />
C4) Extragerea de inregistrari dintr-un tabel<br />
Pana acum am executat statement-uri SQL care nu returnau nici un set rezultat (result-set).<br />
In cazul anumitor interogari (de exmplu SELECT) vom avea set-uri rezultate.<br />
In programul urmator vom extrage datele introduse in tabelul "studenti" si vom afisa si toate coloanele asociate setului rezultat.<br />
<br />
Cod:<br />
<br />
Cod:<br />
/*extragere_date.c */<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
<br />
#include &lt;my_global.h&gt;<br />
#include &lt;mysql.h&gt;<br />
<br />
int main(int argc, char **argv)<br />
{<br />
&nbsp;&nbsp;MYSQL *conn;<br />
&nbsp;&nbsp;MYSQL_RES *result;<br />
&nbsp;&nbsp;MYSQL_ROW row;<br />
&nbsp;&nbsp;int num_fields;<br />
&nbsp;&nbsp;MYSQL_FIELD *field;<br />
&nbsp;&nbsp;int i;<br />
<br />
&nbsp;&nbsp;conn = mysql_init(NULL);<br />
&nbsp;&nbsp;if (conn == NULL) <br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la initializare %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;if (mysql_real_connect(conn, "localhost", "username", "parola", "info_studenti", 0, NULL, 0) == NULL)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Eroare la conexiune catre server %u: %s&#92;n", mysql_errno(conn), mysql_error(conn));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;mysql_query(conn, "SELECT * FROM studenti");<br />
&nbsp;&nbsp;result = mysql_store_result(conn);<br />
<br />
&nbsp;&nbsp;if (result == NULL)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "Nu am gasit nici o inregistrare &#92;n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;num_fields = mysql_num_fields(result);<br />
<br />
&nbsp;&nbsp;while ((row = mysql_fetch_row(result)))<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; num_fields; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (i == 0) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(field = mysql_fetch_field(result)) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s ", field-&gt;name);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("&#92;n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s ", row[i] ? row[i] : "NULL");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;printf("&#92;n");<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;mysql_free_result(result);<br />
&nbsp;&nbsp;mysql_close(conn);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Explicatii:<br />
<br />
mysql_query(conn, "SELECT * FROM studenti");<br />
-> executam urmatoarea interogare pentru a obtine toate inregistrarile din tabelul "studenti": SELECT * FROM studenti<br />
<br />
result = mysql_store_result(conn);<br />
-> apelam mysql_store_result() pentru a "stoca" rezultatul interogarii<br />
<br />
num_fields = mysql_num_fields(result);<br />
-> num_fields va contine numarul de coloane asociat setului "res"<br />
<br />
while ((row = mysql_fetch_row(result)))<br />
{<br />
   ....<br />
}<br />
-> parcurgem setul rezultat in urma interogarii line cu linie<br />
<br />
for (i = 0; i < num_fields; i++)<br />
{ <br />
   ...<br />
}<br />
-> pentru fiecare linie a setului parcurgem fiecare coloana<br />
<br />
if (i == 0) <br />
{<br />
    while(field = mysql_fetch_field(result)) <br />
    {<br />
        printf("%s ", field->name);<br />
    }<br />
    printf("\n");<br />
} <br />
-> inainte de a afisa prima linie a setului, afisam numele tuturor coloanelor<br />
<br />
printf("%s ", row ? row[i] : "NULL");<br />
-> [i]afisam linia curenta a setului apoi continuam iteratia pana cand parcurgem toate liniile setului<br />
<br />
Compilare:<br />
%> gcc extragere_date.c -o extragere_date `mysql_config --cflags --libs`<br />
<br />
Executie:<br />
%> chmod +x extragere_date<br />
%> ./extragere_date <br />
id nume media <br />
1 Ion 7.77 <br />
2 Gheorghe 8 <br />
3 Maria 9.5 <br />
4 Vasile 10 <br />
5 Dumitru 5<br />
<br />
In continuare prezint o serie de comenzi utile ce pot fi incercate atat utilizand un utilitar gen mysql sau din cod, programatic, folosind exemplele de mai sus:<br />
<br />
SHOW DATABASES; -> afiseaza totate bazele de date aflate pe server-ul MYSQL<br />
CREATE DATABASE  baza_de_date; -> creeaza o noua baza de date avand numele baza_de_date<br />
USE baza_date; -> selecteaza baza de date cu numele baza_de_date. Toate operatiile ulterioare se vor face pe aceasta baza de date (pana cand bineinteles, selectam alta)<br />
SHOW TABLES; -> afiseaza numele tuturor tabelelor bazei de date selectate curent<br />
SHOW COLUMNS FROM nume_tabel; ->ofera informatii despre coloanele tabelului nume_tabe <br />
DROP_TABLE nume_tabel; -> sterge un tabel numit nume_tabel din baza de date curent selectata<br />
DROP_DATABASE nume_database; -> sterge baza de date numita nume_database<br />
<br />
Exista multe alte comenzi, dar va trebui sa cititi help-ul pentru a le afla.<br />
<br />
In continuare se prezinta un exemplu de utilizare al comenzilor invatate folosind utilitarul mysql:<br />
<br />
 %> mysql -u root -p<br />
Enter password: <br />
Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
Your MySQL connection id is 43<br />
Server version: 5.0.38-Ubuntu_0ubuntu1.4-log Ubuntu 7.04 distribution<br />
<br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br />
<br />
mysql> SHOW DATABASES;<br />
+--------------------+<br />
| Database           |<br />
+--------------------+<br />
| information_schema | <br />
| mysql              | <br />
| testdb11           | <br />
+--------------------+<br />
3 rows in set (0.00 sec)<br />
<br />
mysql> CREATE DATABASE  baza_de_date;<br />
Query OK, 1 row affected (0.00 sec)<br />
<br />
mysql> USE baza_de_date;<br />
Database changed<br />
<br />
mysql> SHOW TABLES;<br />
Empty set (0.00 sec)<br />
<br />
mysql> CREATE TABLE studenti(id int not null primary key auto_increment, nume varchar(20), media double);<br />
Query OK, 0 rows affected (0.01 sec)<br />
<br />
mysql> SHOW TABLES;<br />
+------------------------+<br />
| Tables_in_baza_de_date |<br />
+------------------------+<br />
| studenti               | <br />
+------------------------+<br />
1 row in set (0.00 sec)<br />
<br />
mysql> SHOW COLUMNS FROM studenti;<br />
+-------+-------------+------+-----+---------+----------------+<br />
| Field | Type        | Null | Key | Default | Extra          |<br />
+-------+-------------+------+-----+---------+----------------+<br />
| id    | int(11)     | NO   | PRI | NULL    | auto_increment | <br />
| nume  | varchar(20) | YES  |     | NULL    |                | <br />
| media | double      | YES  |     | NULL    |                | <br />
+-------+-------------+------+-----+---------+----------------+<br />
3 rows in set (0.00 sec)<br />
<br />
mysql> SELECT * FROM studenti;<br />
Empty set (0.00 sec)<br />
<br />
mysql> INSERT INTO studenti(nume, media) VALUES('Ion', 7.77);<br />
Query OK, 1 row affected (0.00 sec)<br />
<br />
mysql> SELECT * FROM studenti;<br />
+----+------+-------+<br />
| id | nume | media |<br />
+----+------+-------+<br />
|  1 | Ion  |  7.77 | <br />
+----+------+-------+<br />
1 row in set (0.00 sec)<br />
<br />
mysql> DROP TABLE studenti;<br />
Query OK, 0 rows affected (0.01 sec)<br />
<br />
mysql> SHOW TABLES;<br />
Empty set (0.00 sec)<br />
<br />
mysql> DROP DATABASE baza_de_date;<br />
Query OK, 0 rows affected (0.00 sec)<br />
<br />
mysql> SHOW DATABASES;<br />
+--------------------+<br />
| Database           |<br />
+--------------------+<br />
| information_schema | <br />
| mysql              | <br />
| testdb11           | <br />
+--------------------+<br />
3 rows in set (0.00 sec)<br />
<br />
mysql> quit<br />
Bye<br />
<br />
Tutorialul a fost postat initial pe: http://www.skullbox.info/board/accesarea...t4493.html]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[Tutorial] Analiza programelor C folosind Valgrind]]></title>
			<link>http://suport-programare.net/showthread.php?tid=12</link>
			<pubDate>Thu, 19 Jun 2008 04:53:57 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=12</guid>
			<description><![CDATA[Analiza programelor utilizand Valgrind<br />
<br />
Acest tutorial prezinta un utilitar foarte bun pentru analiza codului: valgrind.<br />
Valgrind ruleaza doar pe Linux, deci aveti nevoie de un sistem Linux pentru a urmari acest tutorial.<br />
<br />
Valgrind este un tool pentru debugging si profiling, foarte util pentru detectarea unei game largi de erori de programare.<br />
<br />
Cum functioneaza: <br />
- valgrind este in esenta un emulator software al procesorului host<br />
- cand verificam un executabil utilizand valgrind, rulam acel executabil in mediul simulat<br />
- valgrind contine utilitare pentru debugging si profiling, capabile sa detecteze o gama larga de probleme (precum memory leaks, accesarea memoriei dezlocate, etc ...)<br />
<br />
Valgrind contine urmatoarele utilitare:<br />
<br />
A) Memcheck -> detecteaza urmatoarele probleme de accesare a memoriei:<br />
- memory leaks<br />
- folosirea memoriei neinitializate<br />
- dezalocare memoriei de mai multe ori<br />
- accesarea memoriei deja dezalocate<br />
- accese "out of bounds" al zonelor de memorie alocate dinamic<br />
- scrieri si citiri invalide pe stiva<br />
<br />
B) Cachegrind -> profiler pentru cache-uri.<br />
Util pentru a determina in ce masura performanta programului are de suferit din cauza cache miss-urilor<br />
<br />
C) Callgrind -> smilar Cachegrind-ului, dar ofera suport extins pentru callgraph-uri<br />
<br />
D) Massif -> este un profiler pentru heap<br />
Util pentru a urmari consumul de memorie alocata dinamic (pe heap) a programului, numarul de blocuri alocate de catre manager-ul de heap, etc ...<br />
<br />
E) Helgrind -> detecteaza probleme de sincronizare intre thread-uri, in programele multithreaded<br />
Sunt suportate thread-urile POSIX.<br />
Exemple de probleme detectate:<br />
- deadlock-uri datorate ordinii de lock-ing a mutex-urilor<br />
- accesare unor date de pe mai multe thread-uri fara folosirea unui mecanism de sincronizare (race condition)<br />
<br />
De departe cel mai folosit utilitar este "Memcheck".<br />
Tutorialul se va axa pe folosirea acestui utilitar.<br />
<br />
1.) In primul rand hai sa vedem cum arata raportul oferit de catre valgrind pentru un program care nu are nici o problema in utilizarea memoriei alocate dinamic.<br />
<br />
/* no_error.c */<br />
<br />
Cod:<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;printf("Valoarea setata este %d&#92;n", *p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare:<br />
%> gcc -O0 -g no_error.c -o no_error<br />
<br />
Rulare:<br />
%> valgrind ./no_error<br />
==13028== Memcheck, a memory error detector.<br />
==13028== Copyright &copy; 2002-2006, and GNU GPL'd, by Julian Seward et al.<br />
==13028== Using LibVEX rev 1658, a library for dynamic binary translation.<br />
==13028== Copyright &copy; 2004-2006, and GNU GPL'd, by OpenWorks LLP.<br />
==13028== Using valgrind-3.2.1-Debian, a dynamic binary instrumentation framework.<br />
==13028== Copyright &copy; 2000-2006, and GNU GPL'd, by Julian Seward et al.<br />
==13028== For more details, rerun with: -v<br />
==13028== <br />
Valoarea setata este 1<br />
==13028== <br />
==13028== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==13028== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==13028== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.<br />
==13028== For counts of detected errors, rerun with: -v<br />
==13028== All heap blocks were freed -- no leaks are possible.<br />
<br />
Precum vedeti, raportul specifica ca programul face 1 alocare de 4 bytes (ceea ce este corect, deoarece pe sistemul meu tipul int ocupa 4 bytes), si ca memoria alocata este eliberata<br />
<br />
2). Identificare erorilor de tip memory-leak<br />
Sa vedem acum felul in care valgrind raporteaza erorile de tip memory leak.<br />
<br />
/* memory_leak.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main() <br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(20 * sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;int i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; 20; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[i] = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare<br />
%>gcc -O0 -g memory_leak.c -o memory_leak<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./memory_leak<br />
<br />
Output<br />
....<br />
==13422== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==13422== malloc/free: in use at exit: 80 bytes in 1 blocks.<br />
==13422== malloc/free: 1 allocs, 0 frees, 80 bytes allocated.<br />
==13422== For counts of detected errors, rerun with: -v<br />
==13422== searching for pointers to 1 not-freed blocks.<br />
==13422== checked 76,392 bytes.<br />
==13422== <br />
==13422== 80 bytes in 1 blocks are definitely lost in loss record 1 of 1<br />
==13422==    at 0x4C20A69: malloc (vg_replace_malloc.c:149)<br />
==13422==    by 0x4004A9: main (memory_leak.c:5)<br />
==13422== <br />
==13422== LEAK SUMMARY:<br />
==13422==    definitely lost: 80 bytes in 1 blocks.<br />
==13422==      possibly lost: 0 bytes in 0 blocks.<br />
==13422==    still reachable: 0 bytes in 0 blocks.<br />
==13422==         suppressed: 0 bytes in 0 blocks.<br />
<br />
Observam ca Valgrind raporteaza un memory-leak de 80 de bytes. <br />
Ne mai spune ca blocul de memorie a fost alocat in fisierul memory_leak.c, la linia 5, in functia main<br />
Utilizand aceste informatii, identificam urmatoarea line sursa:<br />
int *p = (int *)malloc(20 * sizeof(int));<br />
in care alocam 80 de bytes (20 * sizeof(int)). Aceasta zona de memorie alocata nu mai este dezalocata in program, ceea ce duce la aparitia unui leak<br />
<br />
3) Dezalocarea aceleiasi zone de memorie de mai multe ori<br />
<br />
/* double_free.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare<br />
%> gcc -O0 -g double_free.c -o double_free<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./double_free<br />
<br />
Output<br />
.....<br />
==13998== Invalid free() / delete / delete[] <br />
==13998==    at 0x4C2067E: free (vg_replace_malloc.c:233)<br />
==13998==    by 0x400519: main (double_free.c:8) <br />
==13998==  Address 0x4042030 is 0 bytes inside a block of size 4 free'd <br />
==13998==    at 0x4C2067E: free (vg_replace_malloc.c:233)<br />
==13998==    by 0x400510: main (double_free.c:7) <br />
==13998== <br />
==13998== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==13998== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==13998== malloc/free: 1 allocs, 2 frees, 4 bytes allocated.<br />
==13998== For counts of detected errors, rerun with: -v<br />
==13998== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca am avut o eroare de tip "invalid free".<br />
Ne mai spune ca am avut o singura alocare de memorie (4 bytes), dar doua operatii de dezalocare.<br />
Mai vedem ca eroarea este localizata in fisierul double_free.c, in functia main, la linia 8.<br />
Avand aceste informatii, identificam linia care a cauzat problema ca fiind:<br />
free(p);  -> al doilea apel al lui free, care nu trebuia facut si care a cauzat eroarea de tip "double free"<br />
<br />
4) Utilizarea memoriei deja dezalocate<br />
<br />
/* deallocated_memory_use.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
In acest program, la linia 8: *p=2, accesez o zona de memorie care a fost deja dezalocata.<br />
<br />
Compilare<br />
%>gcc -O0 -g deallocated_memory_use.c -o deallocated_memory_use<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./deallocated_memory_use<br />
<br />
Output<br />
....<br />
==14615== Invalid write of size 4<br />
==14615==    at 0x400515: main (deallocated_memory_use.c:8)<br />
==14615==  Address 0x4042030 is 0 bytes inside a block of size 4 free'd<br />
==14615==    at 0x4C2067E: free (vg_replace_malloc.c:233)<br />
[/b]==14615==    by 0x400510: main (deallocated_memory_use.c:7)[/b]<br />
==14615== <br />
==14615== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==14615== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==14615== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.<br />
==14615== For counts of detected errors, rerun with: -v<br />
==14615== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca avem un acces invalid la memorie, de tip scriere, pe 4 bytes. Accesul se face deallocated_memory_use.c, in functia main, la linia 8.<br />
Folosind aceste informatii, identificam linia sursa care a cauzat problema:<br />
*p = 2;<br />
<br />
5) Folosirea memoriei neinitializate<br />
<br />
/* uninit_variable_use.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;int y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (x &gt; 10)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 2;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
In acest exemplu, y se va seta la o valoare care depinde de valoarea lui x, care este o variabila neinitializata.<br />
<br />
Compilare<br />
%> gcc -O0 -g uninit_variable_use.c -o uninit_variable_use<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./uninit_variable_use<br />
<br />
Output<br />
....<br />
==15307== Conditional jump or move depends on uninitialised value(s)<br />
==15307==    at 0x400450: main (uninit_variable_use.c:8)<br />
==15307== <br />
==15307== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==15307== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==15307== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.<br />
==15307== For counts of detected errors, rerun with: -v<br />
==15307== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca, la linia 8, in functia main, in fisierul uninit_variable_use.c, avem un salt conditionat care depinde de o valoare neinitializata.<br />
Folosind aceste informatii, identificam linia sursa care a cauzat problema ca fiind:<br />
 if (x > 10)<br />
<br />
6) Accesare "out of bounds" pentru zone de memorie alocate dinamic<br />
<br />
/* out_of_bounds.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main() <br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(20 * sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;int i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; 20; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[i] = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;p[20] = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Accesul out of bounds se face la linia:  p[20] = 0 <br />
<br />
Compilare <br />
%>gcc -O0 -g out_of_bounds.c -o out_of_bounds<br />
<br />
Executie <br />
%>valgrind --leak-check=full --show-reachable=yes ./out_of_bounds<br />
<br />
Output <br />
....<br />
==17979== Invalid write of size 4<br />
==17979==    at 0x40052E: main (out_of_bounds.c:11)<br />
==17979==  Address 0x4042080 is 0 bytes after a block of size 80 alloc'd<br />
==17979==    at 0x4C20A69: malloc (vg_replace_malloc.c:149)<br />
==17979==    by 0x4004F9: main (out_of_bounds.c:5)<br />
==17979== <br />
==17979== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==17979== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==17979== malloc/free: 1 allocs, 1 frees, 80 bytes allocated.<br />
==17979== For counts of detected errors, rerun with: -v<br />
==17979== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca a avut loc o scriere invalida pe 4 bytes, la linia 11, in fisierul out_of_bounds.c, in functia main. Scrierea a avut loc in afara zonei de memorie alocate dinamic la linia 5.<br />
<br />
<br />
Valgrind nu este capabil sa detecteze orice problema privind utilizarea memoriei.<br />
<br />
Sa vedem cateva tipuri de erori pe care valgrind nu le poate detecta.<br />
<br />
- accesele out of bounds pentru array-urile alocate static.<br />
<br />
/* static_out_of_bounds.c */ <br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp; int arr[20];<br />
&nbsp;&nbsp;&nbsp;&nbsp; arr[20] = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
}<br />
<br />
In acest program, arr[20] = 0 genereaza un acces out of bounds<br />
<br />
Compilare<br />
%>gcc -O0 -g static_out_of_bounds.c -o static_out_of_bounds<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./static_out_of_bounds<br />
<br />
Output<br />
==21780== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==21780== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==21780== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.<br />
==21780== For counts of detected errors, rerun with: -v<br />
==21780== All heap blocks were freed -- no leaks are possible.<br />
<br />
Precum se vede, eroarea nu a fost detectata de catre valgrind<br />
<br />
-  incercarile de alocare dinamica a unei zone de memorie de 0 bytes (alte tool-uri, precum Electric Fence, sunt capabile sa detecteze aceasta eroare)<br />
<br />
/* zero_bytes_alloc.c */ <br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare<br />
%>gcc -O0 -g zero_bytes_alloc.c -o zero_bytes_alloc<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./zero_bytes_alloc<br />
<br />
Output<br />
==22020== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==22020== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==22020== malloc/free: 1 allocs, 1 frees, 0 bytes allocated.<br />
==22020== For counts of detected errors, rerun with: -v<br />
==22020== All heap blocks were freed -- no leaks are possible.<br />
<br />
Precum se vede, valgrind nu a detectat nici aceasta problema.]]></description>
			<content:encoded><![CDATA[Analiza programelor utilizand Valgrind<br />
<br />
Acest tutorial prezinta un utilitar foarte bun pentru analiza codului: valgrind.<br />
Valgrind ruleaza doar pe Linux, deci aveti nevoie de un sistem Linux pentru a urmari acest tutorial.<br />
<br />
Valgrind este un tool pentru debugging si profiling, foarte util pentru detectarea unei game largi de erori de programare.<br />
<br />
Cum functioneaza: <br />
- valgrind este in esenta un emulator software al procesorului host<br />
- cand verificam un executabil utilizand valgrind, rulam acel executabil in mediul simulat<br />
- valgrind contine utilitare pentru debugging si profiling, capabile sa detecteze o gama larga de probleme (precum memory leaks, accesarea memoriei dezlocate, etc ...)<br />
<br />
Valgrind contine urmatoarele utilitare:<br />
<br />
A) Memcheck -> detecteaza urmatoarele probleme de accesare a memoriei:<br />
- memory leaks<br />
- folosirea memoriei neinitializate<br />
- dezalocare memoriei de mai multe ori<br />
- accesarea memoriei deja dezalocate<br />
- accese "out of bounds" al zonelor de memorie alocate dinamic<br />
- scrieri si citiri invalide pe stiva<br />
<br />
B) Cachegrind -> profiler pentru cache-uri.<br />
Util pentru a determina in ce masura performanta programului are de suferit din cauza cache miss-urilor<br />
<br />
C) Callgrind -> smilar Cachegrind-ului, dar ofera suport extins pentru callgraph-uri<br />
<br />
D) Massif -> este un profiler pentru heap<br />
Util pentru a urmari consumul de memorie alocata dinamic (pe heap) a programului, numarul de blocuri alocate de catre manager-ul de heap, etc ...<br />
<br />
E) Helgrind -> detecteaza probleme de sincronizare intre thread-uri, in programele multithreaded<br />
Sunt suportate thread-urile POSIX.<br />
Exemple de probleme detectate:<br />
- deadlock-uri datorate ordinii de lock-ing a mutex-urilor<br />
- accesare unor date de pe mai multe thread-uri fara folosirea unui mecanism de sincronizare (race condition)<br />
<br />
De departe cel mai folosit utilitar este "Memcheck".<br />
Tutorialul se va axa pe folosirea acestui utilitar.<br />
<br />
1.) In primul rand hai sa vedem cum arata raportul oferit de catre valgrind pentru un program care nu are nici o problema in utilizarea memoriei alocate dinamic.<br />
<br />
/* no_error.c */<br />
<br />
Cod:<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;printf("Valoarea setata este %d&#92;n", *p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare:<br />
%> gcc -O0 -g no_error.c -o no_error<br />
<br />
Rulare:<br />
%> valgrind ./no_error<br />
==13028== Memcheck, a memory error detector.<br />
==13028== Copyright &copy; 2002-2006, and GNU GPL'd, by Julian Seward et al.<br />
==13028== Using LibVEX rev 1658, a library for dynamic binary translation.<br />
==13028== Copyright &copy; 2004-2006, and GNU GPL'd, by OpenWorks LLP.<br />
==13028== Using valgrind-3.2.1-Debian, a dynamic binary instrumentation framework.<br />
==13028== Copyright &copy; 2000-2006, and GNU GPL'd, by Julian Seward et al.<br />
==13028== For more details, rerun with: -v<br />
==13028== <br />
Valoarea setata este 1<br />
==13028== <br />
==13028== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==13028== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==13028== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.<br />
==13028== For counts of detected errors, rerun with: -v<br />
==13028== All heap blocks were freed -- no leaks are possible.<br />
<br />
Precum vedeti, raportul specifica ca programul face 1 alocare de 4 bytes (ceea ce este corect, deoarece pe sistemul meu tipul int ocupa 4 bytes), si ca memoria alocata este eliberata<br />
<br />
2). Identificare erorilor de tip memory-leak<br />
Sa vedem acum felul in care valgrind raporteaza erorile de tip memory leak.<br />
<br />
/* memory_leak.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main() <br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(20 * sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;int i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; 20; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[i] = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare<br />
%>gcc -O0 -g memory_leak.c -o memory_leak<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./memory_leak<br />
<br />
Output<br />
....<br />
==13422== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==13422== malloc/free: in use at exit: 80 bytes in 1 blocks.<br />
==13422== malloc/free: 1 allocs, 0 frees, 80 bytes allocated.<br />
==13422== For counts of detected errors, rerun with: -v<br />
==13422== searching for pointers to 1 not-freed blocks.<br />
==13422== checked 76,392 bytes.<br />
==13422== <br />
==13422== 80 bytes in 1 blocks are definitely lost in loss record 1 of 1<br />
==13422==    at 0x4C20A69: malloc (vg_replace_malloc.c:149)<br />
==13422==    by 0x4004A9: main (memory_leak.c:5)<br />
==13422== <br />
==13422== LEAK SUMMARY:<br />
==13422==    definitely lost: 80 bytes in 1 blocks.<br />
==13422==      possibly lost: 0 bytes in 0 blocks.<br />
==13422==    still reachable: 0 bytes in 0 blocks.<br />
==13422==         suppressed: 0 bytes in 0 blocks.<br />
<br />
Observam ca Valgrind raporteaza un memory-leak de 80 de bytes. <br />
Ne mai spune ca blocul de memorie a fost alocat in fisierul memory_leak.c, la linia 5, in functia main<br />
Utilizand aceste informatii, identificam urmatoarea line sursa:<br />
int *p = (int *)malloc(20 * sizeof(int));<br />
in care alocam 80 de bytes (20 * sizeof(int)). Aceasta zona de memorie alocata nu mai este dezalocata in program, ceea ce duce la aparitia unui leak<br />
<br />
3) Dezalocarea aceleiasi zone de memorie de mai multe ori<br />
<br />
/* double_free.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare<br />
%> gcc -O0 -g double_free.c -o double_free<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./double_free<br />
<br />
Output<br />
.....<br />
==13998== Invalid free() / delete / delete[] <br />
==13998==    at 0x4C2067E: free (vg_replace_malloc.c:233)<br />
==13998==    by 0x400519: main (double_free.c:8) <br />
==13998==  Address 0x4042030 is 0 bytes inside a block of size 4 free'd <br />
==13998==    at 0x4C2067E: free (vg_replace_malloc.c:233)<br />
==13998==    by 0x400510: main (double_free.c:7) <br />
==13998== <br />
==13998== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==13998== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==13998== malloc/free: 1 allocs, 2 frees, 4 bytes allocated.<br />
==13998== For counts of detected errors, rerun with: -v<br />
==13998== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca am avut o eroare de tip "invalid free".<br />
Ne mai spune ca am avut o singura alocare de memorie (4 bytes), dar doua operatii de dezalocare.<br />
Mai vedem ca eroarea este localizata in fisierul double_free.c, in functia main, la linia 8.<br />
Avand aceste informatii, identificam linia care a cauzat problema ca fiind:<br />
free(p);  -> al doilea apel al lui free, care nu trebuia facut si care a cauzat eroarea de tip "double free"<br />
<br />
4) Utilizarea memoriei deja dezalocate<br />
<br />
/* deallocated_memory_use.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;*p = 2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
In acest program, la linia 8: *p=2, accesez o zona de memorie care a fost deja dezalocata.<br />
<br />
Compilare<br />
%>gcc -O0 -g deallocated_memory_use.c -o deallocated_memory_use<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./deallocated_memory_use<br />
<br />
Output<br />
....<br />
==14615== Invalid write of size 4<br />
==14615==    at 0x400515: main (deallocated_memory_use.c:8)<br />
==14615==  Address 0x4042030 is 0 bytes inside a block of size 4 free'd<br />
==14615==    at 0x4C2067E: free (vg_replace_malloc.c:233)<br />
[/b]==14615==    by 0x400510: main (deallocated_memory_use.c:7)[/b]<br />
==14615== <br />
==14615== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==14615== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==14615== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.<br />
==14615== For counts of detected errors, rerun with: -v<br />
==14615== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca avem un acces invalid la memorie, de tip scriere, pe 4 bytes. Accesul se face deallocated_memory_use.c, in functia main, la linia 8.<br />
Folosind aceste informatii, identificam linia sursa care a cauzat problema:<br />
*p = 2;<br />
<br />
5) Folosirea memoriei neinitializate<br />
<br />
/* uninit_variable_use.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;int y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (x &gt; 10)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 2;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
In acest exemplu, y se va seta la o valoare care depinde de valoarea lui x, care este o variabila neinitializata.<br />
<br />
Compilare<br />
%> gcc -O0 -g uninit_variable_use.c -o uninit_variable_use<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./uninit_variable_use<br />
<br />
Output<br />
....<br />
==15307== Conditional jump or move depends on uninitialised value(s)<br />
==15307==    at 0x400450: main (uninit_variable_use.c:8)<br />
==15307== <br />
==15307== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==15307== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==15307== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.<br />
==15307== For counts of detected errors, rerun with: -v<br />
==15307== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca, la linia 8, in functia main, in fisierul uninit_variable_use.c, avem un salt conditionat care depinde de o valoare neinitializata.<br />
Folosind aceste informatii, identificam linia sursa care a cauzat problema ca fiind:<br />
 if (x > 10)<br />
<br />
6) Accesare "out of bounds" pentru zone de memorie alocate dinamic<br />
<br />
/* out_of_bounds.c */<br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main() <br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(20 * sizeof(int));<br />
&nbsp;&nbsp;&nbsp;&nbsp;int i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; 20; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[i] = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;p[20] = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Accesul out of bounds se face la linia:  p[20] = 0 <br />
<br />
Compilare <br />
%>gcc -O0 -g out_of_bounds.c -o out_of_bounds<br />
<br />
Executie <br />
%>valgrind --leak-check=full --show-reachable=yes ./out_of_bounds<br />
<br />
Output <br />
....<br />
==17979== Invalid write of size 4<br />
==17979==    at 0x40052E: main (out_of_bounds.c:11)<br />
==17979==  Address 0x4042080 is 0 bytes after a block of size 80 alloc'd<br />
==17979==    at 0x4C20A69: malloc (vg_replace_malloc.c:149)<br />
==17979==    by 0x4004F9: main (out_of_bounds.c:5)<br />
==17979== <br />
==17979== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)<br />
==17979== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==17979== malloc/free: 1 allocs, 1 frees, 80 bytes allocated.<br />
==17979== For counts of detected errors, rerun with: -v<br />
==17979== All heap blocks were freed -- no leaks are possible.<br />
<br />
Raportul ne spune ca a avut loc o scriere invalida pe 4 bytes, la linia 11, in fisierul out_of_bounds.c, in functia main. Scrierea a avut loc in afara zonei de memorie alocate dinamic la linia 5.<br />
<br />
<br />
Valgrind nu este capabil sa detecteze orice problema privind utilizarea memoriei.<br />
<br />
Sa vedem cateva tipuri de erori pe care valgrind nu le poate detecta.<br />
<br />
- accesele out of bounds pentru array-urile alocate static.<br />
<br />
/* static_out_of_bounds.c */ <br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp; int arr[20];<br />
&nbsp;&nbsp;&nbsp;&nbsp; arr[20] = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp; return EXIT_SUCCESS;<br />
}<br />
<br />
In acest program, arr[20] = 0 genereaza un acces out of bounds<br />
<br />
Compilare<br />
%>gcc -O0 -g static_out_of_bounds.c -o static_out_of_bounds<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./static_out_of_bounds<br />
<br />
Output<br />
==21780== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==21780== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==21780== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.<br />
==21780== For counts of detected errors, rerun with: -v<br />
==21780== All heap blocks were freed -- no leaks are possible.<br />
<br />
Precum se vede, eroarea nu a fost detectata de catre valgrind<br />
<br />
-  incercarile de alocare dinamica a unei zone de memorie de 0 bytes (alte tool-uri, precum Electric Fence, sunt capabile sa detecteze aceasta eroare)<br />
<br />
/* zero_bytes_alloc.c */ <br />
<br />
Cod:<br />
#include &lt;stdlib.h&gt;<br />
<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;int *p = (int *)malloc(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_SUCCESS;<br />
}<br />
<br />
Compilare<br />
%>gcc -O0 -g zero_bytes_alloc.c -o zero_bytes_alloc<br />
<br />
Executie<br />
%>valgrind --leak-check=full --show-reachable=yes ./zero_bytes_alloc<br />
<br />
Output<br />
==22020== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)<br />
==22020== malloc/free: in use at exit: 0 bytes in 0 blocks.<br />
==22020== malloc/free: 1 allocs, 1 frees, 0 bytes allocated.<br />
==22020== For counts of detected errors, rerun with: -v<br />
==22020== All heap blocks were freed -- no leaks are possible.<br />
<br />
Precum se vede, valgrind nu a detectat nici aceasta problema.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Cum se codeaza o thema de wordpress]]></title>
			<link>http://suport-programare.net/showthread.php?tid=11</link>
			<pubDate>Tue, 17 Jun 2008 11:09:12 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=11</guid>
			<description><![CDATA[Salut. Cel mai bun loc unde poti sa inveti tutoriale wordpress<br />
Tutorial HTML<br />
Tutorial XHTML<br />
Tutorial CSS<br />
Sper sa'ti foloseasca..]]></description>
			<content:encoded><![CDATA[Salut. Cel mai bun loc unde poti sa inveti tutoriale wordpress<br />
Tutorial HTML<br />
Tutorial XHTML<br />
Tutorial CSS<br />
Sper sa'ti foloseasca..]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Uefa 2008]]></title>
			<link>http://suport-programare.net/showthread.php?tid=10</link>
			<pubDate>Tue, 17 Jun 2008 11:07:04 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=10</guid>
			<description><![CDATA[Astazi joaca Romania - Olanda  Cine credeti ca va castiga meciul?<br />
<br />
Sondajul meu este<br />
Romania 1 - 0 Olanda<br />
<br />
Astept parerile voastre mai jos.]]></description>
			<content:encoded><![CDATA[Astazi joaca Romania - Olanda  Cine credeti ca va castiga meciul?<br />
<br />
Sondajul meu este<br />
Romania 1 - 0 Olanda<br />
<br />
Astept parerile voastre mai jos.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Hey Wazzup ?]]></title>
			<link>http://suport-programare.net/showthread.php?tid=9</link>
			<pubDate>Tue, 17 Jun 2008 10:50:49 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=9</guid>
			<description><![CDATA[Sal, ma cheama Skinnerul A.K.A. Ioan sunt din Austria si bine vam gasit :P]]></description>
			<content:encoded><![CDATA[Sal, ma cheama Skinnerul A.K.A. Ioan sunt din Austria si bine vam gasit :P]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Bancul saptamanii 2]]></title>
			<link>http://suport-programare.net/showthread.php?tid=8</link>
			<pubDate>Mon, 16 Jun 2008 10:46:58 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=8</guid>
			<description><![CDATA[Un somer merge sa se angajeze la Microsoft ca om de servicu. Managerul de acolo il supune unui test de aptitudini: spalatul podelelor, spalatul geamurilor etc. Dupa test ii spune:<br />
- Vei avea un salariu de 30 &#36; pe zi. Lasa-mi adresa de e-mail ca sa-ti trimit formularul sa il completezi si sa-ti spun unde si cand sa vii in prima zi la lucru.<br />
Somerul recunoaste cinstit ca nu are nici calculator, nici adresa de e-mail.<br />
- Atunci inseamna ca tu virtual nu existi si deci nu te pot angaja la Microsoft, ii spune managerul.<br />
Uimit, omul pleaca si nestiind ce altceva ar putea face, cu ultimii 10 &#36; din buzunar cumpara o lada cu 10 kg de rosii de la supermarket, pe care, in doua ore, le revinde cu profit de 100%. Repetand procedeul de mai multe ori in ziua aceea ajunge seara cu aproape 100 &#36; mai mult decat avea dimineata. Asa a realizat ca putea sa traiasca vanzand rosii. Sculandu-se dimineata devreme si culcandu-se noaptea tarziu omul nostru a realizat un profit bun in scurt timp. Apoi si-a cumparat o masina pentru transportul rosiilor, iar la sfarsitul primului an a avut un intreg parc de camioane si o multime de angajati dintre somerii ca si el, toti vanzand rosii. Era momentul ca gandindu-se la viitorul sotiei si al copiilor sa faca o asigurare pe viata. A telefonat deci unei companii de asigurari si a ales o asigurare foarte scumpa, care sa reflecte noua lui situatie de milionar. La sfarsitul convorbirii, persoana cu asigurarea i-a cerut adresa de e-mail pentru a-i trimite documentatia. Cand omul nostru a spus ca nu are asa ceva, persoana de la compania de asigurari a fost uimita:<br />
- Cum ai reusit atunci sa faci o asemenea avere fara internet, e-mail si e-commerce? Imagineaza-ti unde ai fi fost acum daca ai fi fost conectat de la inceput.<br />
Milionarul rosiilor a raspuns prompt:<br />
- Imi imaginez. As fi fost om de serviciu la Microsoft.<br />
Morala :<br />
1) Internetul, e-mail si e-commerce-ul nu trebuie sa ne conduca in viata.<br />
2) Fa-ti un e-mail daca vrei sa fii om de serviciu la Microsoft.<br />
3) Daca nu ai e-mail, dar muncesti din greu, inca poti deveni milionar.<br />
4) Presupunand ca citesti aceasta povestire prin intermediul e-mailului sau internetului esti tot mai aproape de a deveni om de serviciu si tot mai departe de a deveni milionar.]]></description>
			<content:encoded><![CDATA[Un somer merge sa se angajeze la Microsoft ca om de servicu. Managerul de acolo il supune unui test de aptitudini: spalatul podelelor, spalatul geamurilor etc. Dupa test ii spune:<br />
- Vei avea un salariu de 30 &#36; pe zi. Lasa-mi adresa de e-mail ca sa-ti trimit formularul sa il completezi si sa-ti spun unde si cand sa vii in prima zi la lucru.<br />
Somerul recunoaste cinstit ca nu are nici calculator, nici adresa de e-mail.<br />
- Atunci inseamna ca tu virtual nu existi si deci nu te pot angaja la Microsoft, ii spune managerul.<br />
Uimit, omul pleaca si nestiind ce altceva ar putea face, cu ultimii 10 &#36; din buzunar cumpara o lada cu 10 kg de rosii de la supermarket, pe care, in doua ore, le revinde cu profit de 100%. Repetand procedeul de mai multe ori in ziua aceea ajunge seara cu aproape 100 &#36; mai mult decat avea dimineata. Asa a realizat ca putea sa traiasca vanzand rosii. Sculandu-se dimineata devreme si culcandu-se noaptea tarziu omul nostru a realizat un profit bun in scurt timp. Apoi si-a cumparat o masina pentru transportul rosiilor, iar la sfarsitul primului an a avut un intreg parc de camioane si o multime de angajati dintre somerii ca si el, toti vanzand rosii. Era momentul ca gandindu-se la viitorul sotiei si al copiilor sa faca o asigurare pe viata. A telefonat deci unei companii de asigurari si a ales o asigurare foarte scumpa, care sa reflecte noua lui situatie de milionar. La sfarsitul convorbirii, persoana cu asigurarea i-a cerut adresa de e-mail pentru a-i trimite documentatia. Cand omul nostru a spus ca nu are asa ceva, persoana de la compania de asigurari a fost uimita:<br />
- Cum ai reusit atunci sa faci o asemenea avere fara internet, e-mail si e-commerce? Imagineaza-ti unde ai fi fost acum daca ai fi fost conectat de la inceput.<br />
Milionarul rosiilor a raspuns prompt:<br />
- Imi imaginez. As fi fost om de serviciu la Microsoft.<br />
Morala :<br />
1) Internetul, e-mail si e-commerce-ul nu trebuie sa ne conduca in viata.<br />
2) Fa-ti un e-mail daca vrei sa fii om de serviciu la Microsoft.<br />
3) Daca nu ai e-mail, dar muncesti din greu, inca poti deveni milionar.<br />
4) Presupunand ca citesti aceasta povestire prin intermediul e-mailului sau internetului esti tot mai aproape de a deveni om de serviciu si tot mai departe de a deveni milionar.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Tabele in HTML]]></title>
			<link>http://suport-programare.net/showthread.php?tid=7</link>
			<pubDate>Mon, 16 Jun 2008 09:59:46 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=7</guid>
			<description><![CDATA[Tabelele din HTML sunt, parerea mea, un lucru esential si trebuie sa fie printre primele lucruri care le inveti din HTML.Treaba cu aceste tabele nu e una foarte complicata, sunt niste tabele ca oricare altele, cu linii si coloane.<br />
<br />
Un tabel e cuprins intre tag-urile  si . Liniile sunt cuprinse intre  si , iar celulele intre  si . Aveti mai jos un exemplu simplu de tabel in HTML care va arata astfel:<br />
<br />
<br />
Cod:<br />
&lt;table border="1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 1 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 1 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 2 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 2 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 3 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 3 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/table<br />
<br />
<br />
Liniile acestui tabel sunt vizibile (la 1 pixel in acest caz) deoarece atributul border are valoarea 1. Daca acest atribut nu e specificat sau e 0, liniile tabelului nu se vad.<br />
<br />
Fiecare coloana a tabelului poate avea un titlu care e cuprins intre tag-urile  si .Acestea sunt declarate inainte de prima linie si e bine sa fie tot atatea titluri cate coloane sunt.De exemplu :<br />
<br />
<br />
Cod:<br />
&lt;table border="1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;th&gt;Titlu 1&lt;/th&gt;&lt;th&gt;Titlu 2&lt;/th&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 1 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 1 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 2 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 2 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 3 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 3 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/table&gt;<br />
<br />
<br />
Alte atribute ale tabelului sunt cellspacing care indica spatiul dintre celule (in pixeli), cellpadding care indica spatiul dintre continutul celulei si marginea ei, align care poate lua valorile left, center sau right si, bineinteles, indica aliniamentul tabelului.<br />
<br />
Aveti aici un exemplu destul de complex si colorat:<br />
<br />
<br />
Cod:<br />
&lt;table border="2" cellspacing="10" cellpadding="20" bordercolor="#FF0000"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;th bgcolor="#FFFF00"&gt;Titlu 1&lt;/th&gt;&lt;th bgcolor="#FFFF00"&gt;Titlu 2&lt;/th&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td bgcolor="#CCCCCC"&gt;Linia 1 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 1 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 2 - Coloana 1&lt;/td&gt;&lt;td bgcolor="#CCCCCC"&gt;Linia 2 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td bgcolor="#CCCCCC"&gt;Linia 3 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 3 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/table&gt;<br />
<br />
]]></description>
			<content:encoded><![CDATA[Tabelele din HTML sunt, parerea mea, un lucru esential si trebuie sa fie printre primele lucruri care le inveti din HTML.Treaba cu aceste tabele nu e una foarte complicata, sunt niste tabele ca oricare altele, cu linii si coloane.<br />
<br />
Un tabel e cuprins intre tag-urile  si . Liniile sunt cuprinse intre  si , iar celulele intre  si . Aveti mai jos un exemplu simplu de tabel in HTML care va arata astfel:<br />
<br />
<br />
Cod:<br />
&lt;table border="1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 1 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 1 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 2 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 2 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 3 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 3 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/table<br />
<br />
<br />
Liniile acestui tabel sunt vizibile (la 1 pixel in acest caz) deoarece atributul border are valoarea 1. Daca acest atribut nu e specificat sau e 0, liniile tabelului nu se vad.<br />
<br />
Fiecare coloana a tabelului poate avea un titlu care e cuprins intre tag-urile  si .Acestea sunt declarate inainte de prima linie si e bine sa fie tot atatea titluri cate coloane sunt.De exemplu :<br />
<br />
<br />
Cod:<br />
&lt;table border="1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;th&gt;Titlu 1&lt;/th&gt;&lt;th&gt;Titlu 2&lt;/th&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 1 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 1 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 2 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 2 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 3 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 3 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/table&gt;<br />
<br />
<br />
Alte atribute ale tabelului sunt cellspacing care indica spatiul dintre celule (in pixeli), cellpadding care indica spatiul dintre continutul celulei si marginea ei, align care poate lua valorile left, center sau right si, bineinteles, indica aliniamentul tabelului.<br />
<br />
Aveti aici un exemplu destul de complex si colorat:<br />
<br />
<br />
Cod:<br />
&lt;table border="2" cellspacing="10" cellpadding="20" bordercolor="#FF0000"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;th bgcolor="#FFFF00"&gt;Titlu 1&lt;/th&gt;&lt;th bgcolor="#FFFF00"&gt;Titlu 2&lt;/th&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td bgcolor="#CCCCCC"&gt;Linia 1 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 1 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td&gt;Linia 2 - Coloana 1&lt;/td&gt;&lt;td bgcolor="#CCCCCC"&gt;Linia 2 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td bgcolor="#CCCCCC"&gt;Linia 3 - Coloana 1&lt;/td&gt;&lt;td&gt;Linia 3 - Coloana 2&lt;/td&gt;&lt;/tr&gt;<br />
&lt;/table&gt;<br />
<br />
]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Windows XP Service Pack 3]]></title>
			<link>http://suport-programare.net/showthread.php?tid=6</link>
			<pubDate>Wed, 11 Jun 2008 14:42:18 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=6</guid>
			<description><![CDATA[Au scos baietii de la Microsoft al treilea Service Pack pentru Windows XP. Sa-l vedem, oare ce imbunatatiri au adus.<br />
<br />
Click aici pentru descarcare.]]></description>
			<content:encoded><![CDATA[Au scos baietii de la Microsoft al treilea Service Pack pentru Windows XP. Sa-l vedem, oare ce imbunatatiri au adus.<br />
<br />
Click aici pentru descarcare.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Siruri de caractere in Pascal]]></title>
			<link>http://suport-programare.net/showthread.php?tid=5</link>
			<pubDate>Wed, 11 Jun 2008 12:06:24 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=5</guid>
			<description><![CDATA[Un sir de carcatere este o succesiune de carcatere cuprinsa intre doua apostrofuri si poate sa contina orice carcatere:litere mari si mici, caractere speciale ('#','&#36;',etc.) si delimitatori (virgula,spatiu,punct, etc.).<br />
<br />
Un astfel de sir de carcatere cuprins intre apostrofuri poate fi memorat intr-o variabila de tipul predefinit string.La declararea unei variabile de tipul string putem preciza, intre paranteze patrate, lungimea maxima, adica numarul maxim de caractere al sirurilor ce pot fi memorate in variabila respectiva. Daca nu indicam lungimea maxima, atunci compilatorul va stabili lungimea maxima implicita de 255 de caractere.<br />
<br />
Exemplu:<br />
<br />
<br />
Cod:<br />
var s1:string[30]; {s1 poate memora maxim 30 de caractere}<br />
&nbsp;&nbsp;&nbsp;&nbsp; s2:string; {s2 va memora maxim 255 caractere}<br />
<br />
<br />
In urma declararii unei variabile de tip string, compilatorul Pascal aloca memorie pentru variabila respectiva sub forma unui vector de caractere. Ce se va intampla insa atunci cand in variabila se va memora efectiv un sir prin atribuire sau prin citire? Caracterele sirului vor ocupa pozitii consecutive in vector, incepand cu pozitia 1. Pot aparea urmatoarele situatii:<br />
-daca lungimea efectiva a sirului (numarul efectiv de caractere) este mai mica decat lungimea maxima a variabilei (numarul maxim de caractere rezultat din declarare), atunci ultimele pozitii ale vectorului de caractere vor ramane neocupate.<br />
- daca lungimea sirului e mai mare decat lungimea maxima, atunci sirul va fi trunchiat si se vor memora atatea caractere cate sunt declarate.<br />
<br />
Exemplu<br />
<br />
Cod:<br />
var s:string[7];<br />
begin<br />
 s:='suport';<br />
 writeln(s);<br />
 s:='programare';<br />
 writeln(s);<br />
end.<br />
<br />
Acest exemplu va afisa:<br />
suport<br />
program<br />
<br />
Sirul 'suport' e memorat in intregime deoarece are 6 caractere (6]]></description>
			<content:encoded><![CDATA[Un sir de carcatere este o succesiune de carcatere cuprinsa intre doua apostrofuri si poate sa contina orice carcatere:litere mari si mici, caractere speciale ('#','&#36;',etc.) si delimitatori (virgula,spatiu,punct, etc.).<br />
<br />
Un astfel de sir de carcatere cuprins intre apostrofuri poate fi memorat intr-o variabila de tipul predefinit string.La declararea unei variabile de tipul string putem preciza, intre paranteze patrate, lungimea maxima, adica numarul maxim de caractere al sirurilor ce pot fi memorate in variabila respectiva. Daca nu indicam lungimea maxima, atunci compilatorul va stabili lungimea maxima implicita de 255 de caractere.<br />
<br />
Exemplu:<br />
<br />
<br />
Cod:<br />
var s1:string[30]; {s1 poate memora maxim 30 de caractere}<br />
&nbsp;&nbsp;&nbsp;&nbsp; s2:string; {s2 va memora maxim 255 caractere}<br />
<br />
<br />
In urma declararii unei variabile de tip string, compilatorul Pascal aloca memorie pentru variabila respectiva sub forma unui vector de caractere. Ce se va intampla insa atunci cand in variabila se va memora efectiv un sir prin atribuire sau prin citire? Caracterele sirului vor ocupa pozitii consecutive in vector, incepand cu pozitia 1. Pot aparea urmatoarele situatii:<br />
-daca lungimea efectiva a sirului (numarul efectiv de caractere) este mai mica decat lungimea maxima a variabilei (numarul maxim de caractere rezultat din declarare), atunci ultimele pozitii ale vectorului de caractere vor ramane neocupate.<br />
- daca lungimea sirului e mai mare decat lungimea maxima, atunci sirul va fi trunchiat si se vor memora atatea caractere cate sunt declarate.<br />
<br />
Exemplu<br />
<br />
Cod:<br />
var s:string[7];<br />
begin<br />
 s:='suport';<br />
 writeln(s);<br />
 s:='programare';<br />
 writeln(s);<br />
end.<br />
<br />
Acest exemplu va afisa:<br />
suport<br />
program<br />
<br />
Sirul 'suport' e memorat in intregime deoarece are 6 caractere (6]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Ce nu iti place?]]></title>
			<link>http://suport-programare.net/showthread.php?tid=4</link>
			<pubDate>Wed, 11 Jun 2008 10:28:34 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=4</guid>
			<description><![CDATA[Ce credeti ca ar trebui modificat in acest forum? Ce nu va place? Ce parere aveti despre design?]]></description>
			<content:encoded><![CDATA[Ce credeti ca ar trebui modificat in acest forum? Ce nu va place? Ce parere aveti despre design?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Script PHP de cautare in baza de date]]></title>
			<link>http://suport-programare.net/showthread.php?tid=3</link>
			<pubDate>Wed, 11 Jun 2008 10:24:40 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=3</guid>
			<description><![CDATA[Am sa va prezint un script de cautare intr-o baza de date. Pentru asta aveti nevoie de 2 fisiere. Un fisier HTML in care realizam form-ul(chestionarul) de cautare si un fisier php care va contine script-ul propriu-zis de cautare.Fisierul HTML va contine:<br />
<br />
Cod:<br />
&lt;form action="rezultat.php" method="get"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="text" value="Cauta" name="nume" onClick="this.value=''"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="submit" value="Cauta"/&gt;<br />
&lt;/form&gt;<br />
<br />
<br />
Iar in fisierul PHP, care se numeste "rezultat.php" trebuie inlocuit numele host-ului, username-ul, parola si numele bazei de date din primele doua randuri.<br />
<br />
Cod PHP:<br />
&lt;?php&nbsp;&nbsp;&nbsp;&nbsp;mysql_connect("localhost","username","parola")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;mysql_select_db("nume_baza_de_date")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;search=&#36;_GET['nume'];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;sql=mysql_query("SELECT&nbsp;*&nbsp;FROM&nbsp;nume_tabel&nbsp;WHERE&nbsp;nume&nbsp;LIKE&nbsp;'%&#36;search%'");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&#36;rez=mysql_fetch_array(&#36;sql))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo(&#36;rez[numar_coloana]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}?&gt;<br />
<br />
<br />
Mai e de inlocuit nume_tabel din mysql_query cu numele tabelului din baza de date in care se doreste facuta cautarea, nume cu numele coloanei,iar numar_coloana din echo(&#36;rez[numar_coloana]); cu numarul coloanei din tabel in care se doreste facuta cautarea (de mentionat ca numaratoarea coloanelor incepe de la 0).<br />
<br />
Toata aceasta treaba se poate face si intr-un singur fisier cu continutul urmator.<br />
<br />
<br />
Cod PHP:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;form&nbsp;action=""&nbsp;method="get"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;value="Cauta"&nbsp;name="nume"&nbsp;onClick="this.value=''"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="submit"&nbsp;value="Cauta"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/form&gt;&lt;?php&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(isset(&#36;_GET['nume']))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql_connect("localhost","username","parola")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql_select_db("nume_baza_de_date")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;search=&#36;_GET['nume'];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;sql=mysql_query("SELECT&nbsp;*&nbsp;FROM&nbsp;nume_tabel&nbsp;WHERE&nbsp;nume&nbsp;LIKE&nbsp;'%&#36;search%'");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&#36;rez=mysql_fetch_array(&#36;sql))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo(&#36;rez[numar_coloana]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;}?&gt;<br />
<br />
<br />
Puteti reclama orice eroare gasita in acest tutorial sau daca aveti nelamuriri va raspund cu cea mai mare placere.]]></description>
			<content:encoded><![CDATA[Am sa va prezint un script de cautare intr-o baza de date. Pentru asta aveti nevoie de 2 fisiere. Un fisier HTML in care realizam form-ul(chestionarul) de cautare si un fisier php care va contine script-ul propriu-zis de cautare.Fisierul HTML va contine:<br />
<br />
Cod:<br />
&lt;form action="rezultat.php" method="get"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="text" value="Cauta" name="nume" onClick="this.value=''"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="submit" value="Cauta"/&gt;<br />
&lt;/form&gt;<br />
<br />
<br />
Iar in fisierul PHP, care se numeste "rezultat.php" trebuie inlocuit numele host-ului, username-ul, parola si numele bazei de date din primele doua randuri.<br />
<br />
Cod PHP:<br />
&lt;?php&nbsp;&nbsp;&nbsp;&nbsp;mysql_connect("localhost","username","parola")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;mysql_select_db("nume_baza_de_date")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;search=&#36;_GET['nume'];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;sql=mysql_query("SELECT&nbsp;*&nbsp;FROM&nbsp;nume_tabel&nbsp;WHERE&nbsp;nume&nbsp;LIKE&nbsp;'%&#36;search%'");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&#36;rez=mysql_fetch_array(&#36;sql))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo(&#36;rez[numar_coloana]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}?&gt;<br />
<br />
<br />
Mai e de inlocuit nume_tabel din mysql_query cu numele tabelului din baza de date in care se doreste facuta cautarea, nume cu numele coloanei,iar numar_coloana din echo(&#36;rez[numar_coloana]); cu numarul coloanei din tabel in care se doreste facuta cautarea (de mentionat ca numaratoarea coloanelor incepe de la 0).<br />
<br />
Toata aceasta treaba se poate face si intr-un singur fisier cu continutul urmator.<br />
<br />
<br />
Cod PHP:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;form&nbsp;action=""&nbsp;method="get"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;value="Cauta"&nbsp;name="nume"&nbsp;onClick="this.value=''"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="submit"&nbsp;value="Cauta"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/form&gt;&lt;?php&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(isset(&#36;_GET['nume']))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql_connect("localhost","username","parola")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql_select_db("nume_baza_de_date")&nbsp;or&nbsp;die(mysql_error());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;search=&#36;_GET['nume'];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;sql=mysql_query("SELECT&nbsp;*&nbsp;FROM&nbsp;nume_tabel&nbsp;WHERE&nbsp;nume&nbsp;LIKE&nbsp;'%&#36;search%'");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(&#36;rez=mysql_fetch_array(&#36;sql))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo(&#36;rez[numar_coloana]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;}?&gt;<br />
<br />
<br />
Puteti reclama orice eroare gasita in acest tutorial sau daca aveti nelamuriri va raspund cu cea mai mare placere.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Bancul saptamanii 1]]></title>
			<link>http://suport-programare.net/showthread.php?tid=2</link>
			<pubDate>Wed, 11 Jun 2008 09:25:16 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=2</guid>
			<description><![CDATA[Cica un turist american merge la Bucuresti si se urca si el intr-un taxi. Merg ei ce merg prin oras si trec pe langa primarie, la care intreaba americanul:<br />
- In cat timp a fost construita cladirea asta?<br />
- Pai...in vreo 6 luni, raspunde taximetristul nestiind exact.<br />
- Ah...noi o construiam in 3 luni, spune americanul.<br />
Mai merg ei ce merg si trec pe langa Cotroceni. Americanul iar:<br />
- In cat timp a fost construita cladirea asta?<br />
- In 3 luni.<br />
- Noi o faceam intr-o luna.<br />
Dupa ce mai merg putin ajung la Palatul Parlamentului.Americanul uimit de cat de mare e cladirea intreaba:<br />
- In cat timp a fost construita cladirea asta?<br />
La care taximetristul deja exasperat:<br />
- Nu stiu ca dimineata nu era aici.]]></description>
			<content:encoded><![CDATA[Cica un turist american merge la Bucuresti si se urca si el intr-un taxi. Merg ei ce merg prin oras si trec pe langa primarie, la care intreaba americanul:<br />
- In cat timp a fost construita cladirea asta?<br />
- Pai...in vreo 6 luni, raspunde taximetristul nestiind exact.<br />
- Ah...noi o construiam in 3 luni, spune americanul.<br />
Mai merg ei ce merg si trec pe langa Cotroceni. Americanul iar:<br />
- In cat timp a fost construita cladirea asta?<br />
- In 3 luni.<br />
- Noi o faceam intr-o luna.<br />
Dupa ce mai merg putin ajung la Palatul Parlamentului.Americanul uimit de cat de mare e cladirea intreaba:<br />
- In cat timp a fost construita cladirea asta?<br />
La care taximetristul deja exasperat:<br />
- Nu stiu ca dimineata nu era aici.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[UEFA Euro 2008]]></title>
			<link>http://suport-programare.net/showthread.php?tid=1</link>
			<pubDate>Sun, 08 Jun 2008 05:35:00 -0500</pubDate>
			<guid isPermaLink="false">http://suport-programare.net/showthread.php?tid=1</guid>
			<description><![CDATA[Uite ca am ajuns iar si noi intr-un turneu final. Pana unde crezi ca va ajunge Romania? Va trece de "grupa mortii"? :) Ne-au incurajat destul de mult rezultatele de egalitate obtinute cu campioana si vice-campioana mondiala?]]></description>
			<content:encoded><![CDATA[Uite ca am ajuns iar si noi intr-un turneu final. Pana unde crezi ca va ajunge Romania? Va trece de "grupa mortii"? :) Ne-au incurajat destul de mult rezultatele de egalitate obtinute cu campioana si vice-campioana mondiala?]]></content:encoded>
		</item>
	</channel>
</rss>