The Dark Side of Hardware Upgrade Forum

...bringing out the worst in you since 2003...
Oggi è mer ott 21, 2026 11:01 am

Tutti gli orari sono UTC +1 ora


-->
-->

Apri un nuovo argomento Rispondi all’argomento  [ 23 messaggi ] 
Autore Messaggio
 Oggetto del messaggio: Aiutatemi!!!! Vi prego!!!!!
MessaggioInviato: mar mar 04, 2003 10:08 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
Ragazzi!!!! Entro lunedì devo saper scrivere un programma su c!!!!
Ditemi se c'è qc opuscolo che mi permetta di farlo o qss cosa. L'importante che entro lunedì sappia mettere qcs su c.


Grazie.



P.S. C'è qcn che va al polimi?

Ora sono stanco! Vado a nanna. Mi aspetto migliaia di risposte per domani.


Grazie ancora.


P.S. Scusa Lucio se l'ho messo come importante, ma per me è vitale.
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mar mar 04, 2003 10:13 pm 
Ho qualcosa per te, ma ora vado a cena. Dopo ti posto. ;)

LuVi
Top
  
 
 Oggetto del messaggio:
MessaggioInviato: mar mar 04, 2003 10:15 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
LuVi ha scritto:
Ho qualcosa per te, ma ora vado a cena. Dopo ti posto. ;)

LuVi
Grazie, ti riveli sempre di più un amico. Ho promesso ad Irene che la porterò a Roma per fine anno. Se riesco a mantenere la promessa, ti porto a cena con Annabella.



Grazie
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mar mar 04, 2003 10:16 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
P.S. Buon Appetito.
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mar mar 04, 2003 10:56 pm 
Grazie. ;) Per così poco. ;) I tutorial che pensavo li ho in ufficio, qui ti copio e incollo qualcosa e dei link, in fondo.
Fai cut & paste di questo minitutorial, è utile per cominciare. ;)

Tutorial N° 1 sul C ANSI

Niente prefazione, se vi chiedete perchè imparare il c ansi cestinate il tutorial :).

Quello che ci serve per programmare in c, oltre al cervello, è un compilatore: personalmente tra quelli free io consiglio il dev-c++ che secondo me è un buon compilatore (diffidate da chi vi dice che lcc è un buon compilatore :)). Comunque il miglior compilatore è sicuramente il vc++. Per chi usa un sistema unix(linux ecc.) il problema non si pone dato che c'è il gcc :).

Avete il compilatore? Avete il cervello? Bene allora direi che possiamo iniziare.

Cominciamo con un pò di teoria :). Inanzitutto vorrei dire che il c è stato creato nel 1972 nei laboratori della Bell Telephone. Come mai il nome c ? Semplicemente perchè venne dopo il b: un'altro linguaggio sempre sviluppato per la Bell (le origini del nome b sono ovvie :)). Data la flessibilità e la potenza del liguaggio c, esso si diffuse anche al di fuori dei laboratori della Bell. Ben presto però molte aziende svilupparono una versione personale del linguaggio che portò a logici problemi di portabilità del codice. Per risolvere questi problemi nel 1983 l'istituto degli standards ansi (American National Standards Institute) si incaricò
di definire uno standard per il c(ovvero il c ansi), del quale venne completata la definizione nel 1989 (ecco perchè viene anche definito c89). Nel 1999 è stato ridefinito (c99), ma per ora questo non ci interessa. Il codice che spiegherò nei tuts sul c ansi quindi potrà essere utilizzato su qualsiasi sistema (tanto per mettere le cose in chiaro :)).

Come ho detto il c è un linguaggio flessibile e potente. Il c è un linguaggio di medio livello e cioè riunisce in se le migliori qualità dei linguaggi di basso livello (assembler :)) e di alto livello (basic,pascal,cobol ecc.).

Il c è un linguaggio di poche parole sulle quali è stato costruito il linguaggio. Queste sono le 32 parole definite dal c ansi (c89):

if, else, struct, break, union, void, while, signed, unsigned, long, enum, for, register, extern, switch, typedef, volatile, int, float, const, do, static, double, auto, char, return, goto, sizeof, short, default, continue, case.

Bene dopo tutta questa teoria introduttiva (ho rotto i coglioni lo so :)) cominciamo a fare un pò di pratica: iniziamo col fare il programma più semplice del mondo (ovvero Hello,world).

Attenzione, per fare dei commenti tra righe di codice in c si usa fare così:

/* questo è un commento */

/* Hello.c */

#include <stdio.h>

int main() {

printf("\nHello,world!\n");

return 0;

}

Copiate il codice, aprite il vostro compilatore e incollatelo lì. Salvate il progetto con estensione .c e compilatelo. Bene ora eseguitelo: il programma non fà altro che visualizzare il messaggio "Hello,world!". Ok, allora comincio a spiegare il codice. Il codice parte con #include <nomelib.h> nel nostro caso la libreria è stdio.h che è la libreria che definisce alcune funzioni standard del c ansi, per includere librerie nostre dobbiamo scrivere invece di #include <nomelib.h> :

#include "nomelib.h"

Comunque tratteremo le librerie più avanti. Il main è la funzione con cui parte il programma, l'int che gli ho messo accanto è per stabilire il tipo di valore di ritorno che deve dare la funzione,ma questo lo spiegherò dopo. L'istruzione printf non fà altro che visualizzare un messaggio. Tra i simboli " è compreso il messaggio da visualizzare mentre \n è l'istruzione per andare a capo; return invece termina il programma: nel nostro caso il valore di ritorno sarà 0.

E qui un breve schema sui codici speciali come \n

\b backspace
\n newline
\r carriage return
\t tabulazione orrizzontale
\v tabulazione verticale
\a segnale acustico (beep)
\" simbolo "
\' simbolo '
\\ barra \


Mi sembra piuttosto semplice no?

Creiamo ora un programma che chiede all'utente di inserire una stringa e poi la visualizzi.


#include <stdio.h>

int main() {

char stringa[20]; /* dichiaro la stringa che può contenere massimo 20 caratteri (partendo da 0) */

scanf("%s",&stringa); /* rileva la stringa */

printf("\n%s\n",stringa); /* e la visualizza */

return 0;

}

Allora in questo programma abbiamo incontrato due cose nuove ovvero la dichiarazione di una variabile e l'istruzione scanf.

Per dichiarare una stringa ho utilizzato il tipo di variabile char che di per sè può dichiarare solo un carattere ma il [20] dichiara 20 caratteri. Nell'istruzione scanf("%s",&stringa);, la %s specifica che il dato da rilevare è una stringa. In verità una stringa altro non è che un array, ma questo per ora non ci interessa spiegherò dopo il concetto di array. Ecco comunque i tipi fondamentali di dati in c sui quali si costruiscono gli altri:

char carattere %c
int intero %d
short intero corto %d
long intero lungo %ld
float virgola mobile a precisione singola %f
double virgola mobile a precisione doppia %f


Bene e ora facciamo un semplice programma che chiede di inserire 2 numeri e poi svolga una semplice operazione aritmetica:


#include <stdio.h>

int main() {

/* dichiaro due interi */
int numero1,numero2;

/* chiedo all'utente di inserire due numeri */
printf("\nInserisci due numeri: ");

/* rilevo i due numeri e li assegno alle rispettive variabili */
scanf("%d %d",&numero1,&numero2);

/* visualizzo il risultato sommando un numero all'altro */
printf("\nRisultato: %d\n",numero1+numero2);

return 0;

}


Mi sembra che i commenti siano abbastanza esaurienti no?

Per addizionare segno +, per sottrarre segno -, per moltiplicare segno *, per dividere segno /.

l'istruzione per incrementare un numero di uno: nome_variabile++; per decrementarlo: nome_variabile--;

E ora uno schema sugli operatori relazionali:

== uguale a
!= diverso di
> maggiore di
>= maggiore o uguale a
< minore di
<= minore o uguale a

E ora uno sugli operatori logici

&& AND

|| OR

! NOT

Non avete capito a cosa servono? Niente paura ora faccio un esempio, ma prima introduco l'istruzione "if". Questa istrzuione verifica una evento e se il risultato è quello specificato, vengono eseguite 1 o più istruzioni. Ecco un esempio:

if (nomevariabile==9)
printf("\nciao");

Mi sembra piuttosto chiaro: se la variabile è uguale a 9 visualizzo il messaggio "ciao".

Ma Vediamo un pò di codice.

limite.c

#include <stdio.h>

#define limite 10

/* ecco un'istruzione nuova: #define. Questa istruzione serve per definire qualsiasi cosa vogliate. Nel nostro caso definisce la parola limite = 10 */

int main() {

int x,y; /* dichiaro le variabili x e y */

printf("\nInserisci due numeri: ");

scanf("%d %d",&x,&y); /* rilevo i valori per le variabili x e y */

/* se x e y sono maggiori di limite (10) esegue le operazioni nelle { } */
if (x>limite && y>limite) {

printf("\nSpiacente,");
printf("\nhai superato il limite");

return 1; /* termina il programma */

}

/* se il programma arriva a queste istruzioni vuol dire che x y sono minori di limite */

printf("\nBravo non hai superato il limite");

return 0;

}

Spero che per ora le mie spiegazioni siano state abbastanza chiare (ho cercato di scrivere questo tutorial nel modo più semplice possibile e spero che nessuno sia per ora rimasto indietro).

Bene e ora iniziamo a introdurre le funzioni. Una funzione è una parte di codice che svolge delle istruzioni per conto suo. Le funzioni possono ritornare con dei valori (quello che volete). Per fare in modo che una funzione non dia un valore di ritorno la scriviamo così:

void nome_funzione()

Esempio di funzione:

cubo.c

#include <stdio.h>

int cubo(int x); /* dichiaro la funzione */

int main() {

int lato;

printf("\nInserisci il lato di un quadrato: ");

scanf("%d",&lato);

/*lato = al valore di ritorno della funzione cubo. La funzione cubo
è settata con il parametro lato */
lato=cubo(lato);

printf("\nArea del cubo: %d\n",lato); /* visualizza il valore */

return 0;
}

int cubo(int x) { /* funzione cubo */

return x*x*x; /* il valore di ritorno è x al cubo. */

}

Sforzatevi di capire questo, dato che nel c le funzioni hanno un ruolo fondamentale.

Avete già imparato l'istruzione if, ma ora introdurrò le istruzioni for,while,do..while.

Il ciclo for è quello che forse farete più fatica a capire; la sua sintassi è:

for (condizione_iniziale; condizione; azione)
istruzione/i;

La teoria non è abbastanza esplicativa, quindi passiamo subito alla pratica.

for.c

#include <stdio.h>

int main() {

int x;

/* condizione iniziale x=0, la condizione finchè x<=20, l'azione incrementa x. Finchè x non è uguale a 20 il ciclo for esegue le proprie istruzioni che nel nostro caso visualizzano il valore corrente della x */

for (x=0;x<=20;x++)
printf("\n%d",x);

return 0;
}

Il ciclo while è certamente più semplice di tutti e tre. La sintassi è:

while(condizione)
istruzione;

Ovvero while esegue le sue istruzioni fino a che la condizione non viene smentita. Con queste istruzioni è molto semplice creare cicli infiniti ovvero:

#include <stdio.h>

int main() {

while(1) /* la condizione di while è 1 quindi è sempre vera, questo porta a eseguire
istruzioni che continuano all'infinito. Nel nostro caso il programma
visualizza ripetutamente il messaggio: ciao. */
printf("\nciao");

return 0;
}

Se avessi per esempio scritto:

int x=0;

while(x==1)
istruzioni;

Il ciclo while non avrebbe eseguito le sue istruzioni dato che la condizione era già stata smentita.

Iil ciclo do..while si differenzia da quello while solo perchè compie le sue istruzioni almeno una volta senza verificare la condizione, la sua sintassi è:

do {
istruzioni;
} while(condizione);

do_while.c

#include <stdio.h>

int main() {

int x=0; /* dichiaro x e lo setto uguale a 1 */

/* il ciclo do esegue le sue istruzioni senza verificare la condizione di while
ma dato che la condizione è già smentita l'operazione verrà eseguita
una volta soltanto. */

do {

printf("\nciao");

} while(x==1);

return 0;

}

Spero che abbiate capito anche questi tre cicli dato che sono essenziali.

Per essere esauriente voglio introdurre ancora un ciclo che sarebbe lo switch. Non faccio tante spiegazioni preliminari: partiamo subito dal codice.

switch.c

#include <stdio.h>

int main() {

int x;

scanf("%d",&x);

/* switch prende in considerazione x. */
switch(x) {

/* se il valore è uguale a 1.... */

case 1:
printf("\nbello");
break; /* il break interrompe il ciclo se non lo mettiamo si passa subito
alla prossima istruzione */

/* se il valore è uguale a 2..... */
case 2:
printf("\nbrutto");
break;

}

return 0;
}

A questo punto dovreste essere in grado di capire il ciclo switch. In ogni caso, si impara dalla pratica, rammentatelo sempre. :)

Cominciamo a parlare di array. Noi possiamo dichiarare un qualsiasi tipo di valore che contenga più dati (chiaramente sempre dati dello stesso tipo che corrispondono al tipo di valore).

array.c

#include <stdio.h>

int main() {

int x[10],y; /* dichiaro l'array x e la variabile y */

printf("\nInserisci 10 numeri:\n");

/* per 10 volte prendo un valore e lo metto in una sezione dell'array */
for(y=0;y<10;y++)
scanf("%d",&x[y]);

/* visualizzo tutti i valori dell'array */
for(y=0;y<10;y++)
printf("\nIl valore numero %d = %d",y,x[y]);

return 0;
}

Bene, siamo arrivati all'ultimo degli argomenti trattati da questo tutorial: ovvero i puntatori.

Cosa è un puntatore?

Un puntatore non è altro che una variabile che contiene un indirizzo che punta alla posizione dell'oggetto vero e proprio nella memoria ( so che non è tanto semplice ma sta teoria ci vuole).

Come si fa a dichiarare un puntatore?

Semplicemente così:

tipo_della variabile *nome;

Passiamo subito ad un pò di codice esplicativo.

puntatore.c

#include <stdio.h>

void stampa(char *str); /* dichiaro la funzione che contiene come parametro un puntatore
di tipo char */

int main() {

stampa("ciao"); /* chiamo la funzione settando come parametro la stringa ciao che
verrà assegnata a str. */

return 0;
}

void stampa(char *str) {
printf("\n%s",str); /* visualizzo str che nel nostro caso contiene ciao */
}

Mi sembra di aver spiegato in questo tutorial le basi del c ansi: le funzioni più specifiche incominceremo a vederle dal prossimo tutorial.

Spero sia stato di vostro gradimento questo tutorial (casomai non lo fosse stato: pagatemi e vedrò di farne uno migliore :)).

Alla prossima.

Ntoskrnl

--------------------------------------------------------------------------------------

Tutorial N° 2 sul C ANSI

Per scaricare l'allegato al tutorial clickate qui.

Nel tutorial precedente abbiamo parlato di puntatori,funzioni,variabili,operatori logici ecc (insomma proprio le basi basi), in questo tutorial incominceremo ad andare un pò nello specifico.

Per prima cosa direi di concludere il discorso fatto sui puntatori. Difatti noi abbiamo visto l'uso dei puntatori solo all'interno di una funzione (es: funzione(puntatore)), ora vediamo come utilizzare un puntatore in modo diverso e le funzioni adibite ai puntatori.

esempio.c

#include <stdio.h>
#include <stdlib.h>

int main() {

char *punt;
int x;

printf("\nInserire la quantita di bytes da allocare: ");

scanf("%d",&x);

punt=(char*)malloc(x);

if(!punt) {
printf("\nMemoria non allocata\n");
return 1;
}

printf("\nMemoria allocata\n");

free(punt);

return 0;
}

Questo programma non fa altro che allocare una determinata quantità di memoria e poi la rilascia, ma analizziamo il programma riga per riga, a partire dalle librerie incluse, la stdio la conosciamo bene dato che è quella che definisce le funzioni di IO (Input-Output) del c, la stdlib la dobbiamo includere poichè definisce anche le funzioni adibite ai puntatori (allocazione - rilascio memoria).

char *punt;
int x;

Dopodichè ho dichiarato le due variabili locali (ovvero accessibili unicamente dalla funzione nella quale sono dichiarate) che mi servivano (il puntatore e l'intero che conterrà la quantità di memoria da allocare). Il printf e lo scanf non li spiego e non sapete cosa fanno allora ri/leggete il primo tut.

punt=(char*)malloc(x);

La funzione malloc alloca una determinata quantità di memoria (nel nostro caso la x è il parametro passato alla funzione malloc e indica appunto la quantità di bytes da allocare), la funzione ritorna l'indirizzo della memoria allocata. Bisogna mettere un cast '(char*)' poichè la funzione è dichiarata come 'void *' e char != void quindi....

if(!punt)

Questo if controlla se il puntatore è nullo (corrisponde ad un if(punt==NULL)), se lo è stampa il testo di memoria non allocata e termina. Se non lo è stampa il messaggio di memoria allocata e la rilascia con la funzione free.

Per ora abbiamo visto le istruzioni malloc e free (e queste sono le più importanti), però elenco ancora altre due:

void *calloc(size_t,size_t);

size_t sta per unsigned int (viene definito tramite l'istruzione typedef: typedef unsigned int size_t;).
La funzione calloc al contrario di malloc alloca oggetti, difatti il primo parametro della funzione riguarda il numero di oggetti da allocare mentre il secondo parametro specifica la grandezza di ogni oggetto in byte.

void *realloc(void*,size_t);

Questa funzione invece modifica un'allocazione precedente, il primo parametro riguarda l'indirizzo mentre il secondo specifica la nuova dimensione del blocco. Ma vediamo subito come utilizzare questa funzione.

esempio.c

#include <stdio.h>
#include <stdlib.h>

int main() {

char *punt;
int x;

printf("\nInserire la quantità di bytes da allocare: ");

scanf("%d",&x);

punt=(char*)malloc(x);

if(!punt) {
printf("\nMemoria non allocata\n");
return 1;
}

printf("\nMemoria allocata\n");

punt=(char*)realloc(punt,x++);

if(!punt) {
printf("\nMemoria non riallocata\n");
return 1;
}

printf("\nMemoria riallocata\n");

free(punt);

return 0;
}

questo programma è praticamente uguale al primo, solamente che, dopo aver allocato per la prima volta con malloc modifica il blocco di memoria da noi allocato con realloc e setta la nuova dimensione maggiore di un byte.

Bene direi che per adesso può bastare, parlerò più avanti delle funzioni riguardanti la memoria; mi rendo conto di esser stato anche troppo cattivo, probabilmente non avete compreso niente di puntatori, non importa andate avanti e magari poi ci ritornerete sopra.

Ora poichè nel tutorial precedente non ne ho parlato, in questo accennerò alle strutture.
Per prima cosa chiariamo il concetto di struttura: una struttura non è altro che un raggruppamento di variabili sotto un unico insieme. Le variabili possono essere di tutti i tipi.

struct nuova_struttura {
/* componenti */
};

In questo modo abbiamo solamente definito la struttura ma non l'abbiamo dichiarata. Come farlo ? Ci sono due modi, il primo è di far seguire la dichiarazione della struttura da 1 o più nomi (che saranno poi le variabili-struttura):

struct nuova_struttura {
/* componenti */
} a,b;

a e b sono le variabili-struttura, l'altro modo è quello di definire separatamente le variabili:

struct nuova_struttura {
/* componenti */
};

struct nuova_struttura a,b;

Per accedere ai membri di una funzione siamo costretti ad usare il '.' ovvero:

a.membro

Vediamo subito un piccolo programma :).

esempio.c

#include <stdio.h>

struct mia {
char str[100];
int x;
} a;

int main() {

printf("\nInserisci il tuo nome:\n");
scanf("%s",&a.str);

for(a.x=0;;a.x++) {
if(a.str[a.x]==0) break;
}

printf("\nLa lunghezza del tuo nome corrisponde a %d caratteri\n",a.x);

return 0;
}

Nel programma viene definita e dichiara una struttura, poi viene chiesto il nome dell'utente che viene memorizzato in un membro della struttura, dopodichè ho messo un piccolo ciclo for che calcola la lunghezza della stringa (incrementa la x e controlla ogni singolo byte di a.str: se è uguale a 0 interrompe il ciclo con break); viene poi stampata la lunghezza del nome. Ho accennato alle strutture ma non a caso ho messo in questo esempio un ciclo for per calcolare la lunghezza di una stringa, difatti intendo adesso parlare di stringhe e delle funzioni ad esse adibite (non crederete mica che uno deve scriversi tutti i cicli e le operazioni da solo? :)).

Quindi vediamo subito lo stesso programma, ma invece di usare il for usa la specifica funzione per calcolare la lunghezza.

#include <stdio.h>
#include <string.h>

char str[100];

int main() {

printf("\nInserisci il tuo nome:\n");
scanf("%s",&str);

printf("\nLa lunghezza del tuo nome corrisponde a %d caratteri\n",strlen(str));

return 0;
}

Come possiamo notare oltre alla libreria stdio è inclusa anche la string poichè qui vi sono dichiarate le funzioni riguardanti appunto le stringhe. La funzione strlen ritorna la lunghezza della stringa passata come parametro. Questa era la funzione più elementare. Ancora prima di andare avanti mi sembra opportuno (cazzo se è opportuno :)) aggiungere una cosa, ora noi sappiamo come dichiarare un array di bytes che può contenere una stringa (vedi char str[100]), ma ancora non sappiamo neanche come dichiarare una stringa all'interno del codice. Per fare ciò ci sono due modi:

char str[]="Stringa.";

oppure:

char *str="Stringa.";

Che dichiariate in una o nell'altra maniera non fa alcuna differenza.
Detto ciò andiamo avanti; come dobbiamo fare per confrontare due stringhe? Semplice, dobbiamo semplicemente usare la funzione strcmp, la sua sintassi è questa:

int strcmp(const char*, const char*);

I parametri della funzione corrispondono alle stringhe da confrontare, se le stringhe sono uguali la funzione restituisce il valore 0, altrimenti un valore diverso (-1).

esemio.c

#include <stdio.h>
#include <string.h>

char str[100];
char user[]="Ntoskrnl";

int main() {

printf("\nInserisci il tuo username:\n");
scanf("%s",&str);

if(strcmp(str,user)==0) printf("\nSei Ntoskrnl\n");

else printf("\nNon sei Ntoskrnl\n");

return 0;
}

Mi sembra che questo esempio come gli altri che seguiranno non abbiano bisogno di ulteriori spiegazioni, poichè mi sembrano abbastanza chiari. Okay, abbiamo visto come confrontare due stringhe, vediamo ora come copiare il contenuto di una stringa in un'altra. Per questo vi è la funzione strcpy, la sua sintassi è:

char *strcpy(char*, const char*);

Il primo parametro è la stringa destinazione mentre il secondo è la fonte (ovvio dato che è dichiarato come costante). La funzione ritorna l'indirizzo che punta alla stringa di destinazione.

esempio.c

#include <stdio.h>
#include <string.h>

char destinazione[100];
char fonte[]="ciao";

int main() {

strcpy(destinazione,fonte);
printf("\n%s\n",destinazione);

return 0;
}

Invece di:

strcpy(destinazione,fonte);
printf("\n%s\n",destinazione);

potevo benissimo anche scrivere:

printf("\n%s\n",strcpy(destinazione,fonte));

poichè, se vi ricordate la funzione restituisce una puntatore.
Ma se invece di copiare il contenuto, volessimo concatenare due stringhe? Allora usiamo la funzione strcat.

char *strcat(char *, const char*);

La sintassi è la stessa di strcpy: primo parametro stringa destinazione, secondo parametro stringa fonte e la funzione restituisce un puntatore alla stringa di destinazione.

esempio.c

#include <stdio.h>
#include <string.h>

char str[10]="ciao";

int main() {

strcat(str,"\tciao");
printf("\n%s\n",str);

return 0;
}

Il risultato di questo programma sarà un messaggio "ciao ciao".

Apro ora una piccola parentesi su una funzione che non fa parte proprio dello standard ansi (almeno non mi risulta) nonostante sia supportata da quasi tutti i compilatori. Trattasi della funzione strdup.

char *strdup(const char*);

Questa funzione svolge la stessa funzione di strcpy ma al contrario di quest'ultima, alloca automaticamente la memoria necessaria per contenere la stringa. Difatti la funzione restituisce un puntatore se eseguita con successo, altrimenti restituisce NULL.

esempio.c

#include <stdio.h>
#include <string.h>

char *str;
char testo[]="ciao come va?";

int main() {

if((str=strdup(testo))==NULL)
printf("\nAllocazione non riuscita\n");
else
printf("\n%s\n",str);

return 0;
}

Chiusa parentesi :).

Vediamo ora una funzione che cerca la prima occorenza di una determinato carattere in una stringa.

char *strchr(const char*, int);

Il primo parametro corrisponde alla stringa nella quale cercare il carattere, mentre il secondo è il carattere da cercare. Se il carattere viene trovato la funzione restituisce un indirizzo che punta alla posizione del carattere, altrimenti ritorna NULL.

esempio.c

#include <stdio.h>
#include <string.h>

char c,*pos;
char testo[]="abcdefghilmnopqrstuvz";

int main() {

printf("\nInserisci un carattere: ");
scanf("%c",&c);

pos=strchr(testo,c);

if(!pos)
printf("\nCarattere non trovato\n");
else
printf("\nPosizione carattere: %d\n",pos-testo);

return 0;
}

Come è possbile vedere da questo esempio, per ritrovare la posizione del carattere è necessario fare pos-testo.
Vediamo ora una funzione che forse un giorno (forse) ci tornerà utile.

char *strrev(char*);

Questa funzione non svolge altro che il ruolo di capovolgere la stringa passata come parametro e restituisce un puntatore alla stringa capovolta.

esempio.c

#include <stdio.h>
#include <string.h>

char myname[]="Ntoskrnl";

int main() {

printf("\n%s\n",strrev(myname));

return 0;
}

Ovviamente il programma non fa altro che stampare 'Ntoskrnl' al contrario.

char *strlwr(char*);
char *strupr(char*);

Presento insieme queste due funzioni dato che hanno lo stesso compito (solo che fanno esattamente l'opposto l'una dall'altra). Infatti una funzione converte tutti i caratteri di una determinata stringa in minuscolo, mentre l'altra li converte in maiuscolo.

#include <stdio.h>
#include <string.h>

char myname[]="NtOsKrNl";

int main() {

printf("\n%s",strlwr(myname));
printf("\n%s\n",strupr(myname));

return 0;
}

L'output del programma sarà prima 'ntoskrnl' e poi 'NTOSKRNL'.

Ora dato andiamo un pò per elencazione delle altre funzioni altrimenti si fa notte qua :).

char *strncpy(char*, const char*, size_t);

Stessa cosa di strcpy solo che size_t specifica il numero di caratteri che vanno copiati.

char *strncat(char*, const char, size_t);

Svolge la stessa funzione di strcat ma sempre con lo stesso principio di strncpy.

char *strncmp(const char*, const char*, size_t);

Lo dovreste aver capito :).

char *strrchr(const char*, int);

Stessa cosa di strchr solo che questa funzione cerca l'ultima occorrenza di un carattere in una stringa.

size_t str strcspn(const char*, const char*);

Questa funzione cerca la prima occorrenza di un qualsiasi carattere della seconda stringa all'interno della prima.

size_t strspn(const char*, const char*);

Questa funzione confronta ogni carattere della prima stringa con quelli della seconda e segnala restituisce la posizione del primo carattere che non combacia.

char *strstr(const char*, const char*);

Questa funzione differisce da strchr solo per il fatto che, mentre strchr cerca la prima occorenza di un carattere, strstr cerca la prima occorrenza di una stringa.

Mi sembra di aver elencato quasi tutte le funzioni del c ansi dichiarate nella lib string.h, o perlomeno le più importanti. Poichè ho ancora un pò di tempo direi di riscriverci alcune (ma solo alcune) di queste funzioni :). Trovate i sorgenti nell'allegato al tutorial.

La prima funzione che ho riscritto è l'unica che viene utilizzata anche dalle altre funzioni, si tratta della funzione strlen.

uint mystrlen(const char *str) {

uint len;

for(len=0;;len++) {
if(str[len]==0) break;
}

return len;
}

Dato che avevamo già visto questa funzione non faccio ulteriori commenti a proposito (inoltre mi sembra un codice che potete capire benissimo anche da soli...se così non fosse rimando al primo tut).

La funzione come anche una variabile locale è dichiarata come potete vedere 'uint', è stata definita da me:

#ifndef _UINT_DEFINED
typedef unsigned int uint;
#define _UINT_DEFINED
#endif

Come potete vedere 'uint' viene definita 'unsigned int', questa definizione la potete trovare nella lib che trovate nell'allegato.

Ok, ora vediamo la funzione strcmp.

int mystrcmp(const char *str1,const char *str2) {

uint x,y;

if((x=mystrlen(str1)) < (y=mystrlen(str2))) return -1;
if(x > y) return 1;

for (y=0; y<=x; y++) {

if(str1[y] != str2[y]) return 2;

}

return 0;
}

Come potete vedere questa funzione restituisce 0 se le stringhe sono uguali, -1 se la prima è più piccola della seconda, 1 se è più grande, e 2 se le stringhe sono differenti.

Poi ho riscritto la funzione strlwr:

char *mystrlwr(char *str) {

uint x;

for(x=0; x<mystrlen(str); x++) {

if(str[x]>='A' && str[x]<='Z')
str[x] += 32;

}

return str;

}

Come potete vedere la funzione prende in considerazione ogni carattere della stringa e controlla se il carattere è compreso fa 'A' e 'Z' se lo è aumeta il carattere di 32 ( x +=32 è uguale a x=x+32). Il carattere viene aumentato in base alla tabella ascii (A = 65, a = 97)....Lo stesso discorso vale per strupr.

char *mystrupr(char *str) {

uint x;

for(x=0; x<mystrlen(str); x++) {

if(str[x]>='a' && str[x]<='z')
str[x] -= 32;

}

return str;

}

Come potete vedere è uguale a mystrlwr solo che fa esattamente l'opposto.
Ok, ancora una funzione ansi, abbiamo visto le funzioni di ricerca nelle stringhe e per questo motivo ne riscrivo una anch'io, trattasi strchr.

char *mystrchr(const char *str, int c) {

uint x;

for(x=0; x<mystrlen(str); x++) {

if(str[x]==c) break;

}

return (char*)&str[x];

}

Il codice è molto semplice, l'unica cosa che mi sembra opportuno dire, è con la & di &str[x] viene passato un puntatore anzichè un carattere.

Bene, per ora abbiamo visto solo funzioni ansi, ma mettiamo che il nostro compilatore non supporta alcune funzioni utili (cazzo che cesso di compilatore che avete :)), nessun problema, ce le scriviamo da soli. Comincerei da una funzione che abbiamo già visto prima, ovvero strdup.

char *mystrdup(const char *str) {

uint bytes,x;
char *pointer;

bytes=mystrlen(str);

pointer=(char*)malloc(bytes);

mystrset(pointer,0);

for(x=0; x<bytes; x++)
pointer[x]=str[x];

return pointer;
}

Per poter utilizzare questa funzione è necessario includere la lib stdlib, poichè usiamo la funzione malloc. Come potete notare, nel codice vi è presente una chiamata ad una funzione che non conosciamo, e cioè la funzione mystrset che in verità è la funzione strset che ho riscritto. Anche questa funzione non fa parte dello standard ansi e ha lo scopo di settare tutti i byte di una stringa uguali ad uno da noi specificato. Eccovi la funzione:

char *mystrset(char *str, int c) {

uint x;

for(x=0; x<mystrlen(str); x++)
str[x]=c;

return str;
}

Non è difficile trasformare la seguente nella variante strnset (indovinate per cosa sta la n :)).
Per ora abbiamo visto funzioni facenti parte dello standard e non, ma vediamo ora una funzione che non è supportata da nessun compilatore (o almeno non mi risulta :)). La funzione si chiama mystrucat, come è possibile intuire dal nome questa funzione ha lo scopo di concatenare due stringhe, differisce da strncat per il fatto che mentre strncat concatena una certa quantità di caratteri della seconda stringa, mystrucat concatena da una certa posizione.

char *mystrucat(char *str1, const char *str2, uint up) {

uint len;

for(len=mystrlen(str1); up<mystrlen(str2); len++ && up++)
str1[len]=str2[up];


return str1;
}

Non credo che abbiate bisogno di ulteriori chiarimenti (cazzo siamo solo all'inizio :)). In questo tut ho parlato parecchio di stringhe ma poteva essere anche un altro argomento, era solo per farvi entrare più in confidenza con il linguaggio e le operazioni sulle strighe si prestavano bene a tale proposito.

Nel prossimo tut approfondisco un pò sul linguaggio e inizieremo a parlare di IO. Intanto spero che questo tut sia stato di vostro gradimento (mi aspetto almeno un orgasmo da parte vostra :P).

Ntoskrnl

--------------------------------------------------------------------------------------

Tutorial N° 3 sul C ANSI



Come prima cosa vorrei scusarmi per il tempo che è passato dall&#8217;ultimo tutorial sul c ansi, non voglio neanche dire che non ho avuto tempo, semplicemente troppo spesso è prevalsa l&#8217;insofferenza, farò in modo che non capiti più.



Come ho detto nel secondo, in questo tutorial approfondiremo il linguaggio e inizieremo a parlare di I/O (Input/Output). Per approfondire, ho pensato di spiegare le parole chiave del linguaggio di cui ancora non ho parlato o comunque accennato, ovvero: union, enum, register, extern, volatile, static, auto, goto, sizeof, default e continue.



Ma andiamo per ordine iniziamo con union. Vi ricordate le strutture? Bene perché le union si dichiarano alla stessa maniera, prendiamo per esempio tale union:



union abc {

int a;

char b:

float c;

};



Ora a voi sembrerà una struttura ma c&#8217;è una sostanziale differenza, ovvero tutte le variabili contenute nella union usufruiscono dello stesso spazio in memoria, quindi sarà possibile utilizzare una sola variabile a volta.



La parola chiave enum dichiara invece una struttura enumerativa, si prenda per esempio:



enum alfabeto { a, b, c, d, e };



gli elementi della struttura sono tutti degli interi e il loro valore per default va in ordine ovvero: a = 0, b = 1, c = 2, d = 3, e = 4. Dichiarando l&#8217;insieme:



alfabeto var;



è possibile far assumere a var solo un suo elemento, come per es: var = c;



è possibile anche inizializzare i membri dell&#8217;insieme:



enum alfabeto { a = 5, b, c, d, e };



In questo modo b sarà uguale a 6, c = 7 e così via. Al contrario se dichiariamo:



enum alfabeto { a = 5, b, c = 12, d, e };



a sarà uguale a 5, b = 6, c = 12, d = 13, e = 14. E&#8217; anche possibile inizializzare più membri con lo stesso valore, ma i membri stessi ovviamente non potranno essere ripetuti.



La parola chiave register serve per specificare che la variabile ha priorità assoluta in quanto a velocità e quindi viene mantenuta nei registri, questo serve ovviamente se si sfrutta appieno le risorse. Risulta evidente che solo poche variabili potranno essere dichiarate come register (se ve ne sono troppe il compilatore non ne terrà conto e le tratterà come normali variabili) poiché i registri della cpu non sono infiniti. La sintassi per dichiarare una variabile con register è:



register variable_type x;



La parola chiave extern invece serve nel caso dichiaraste una variabile in un foglio .c e la voleste usare pure in un altro foglio, mi spiego meglio, mettete di aver dichiarato nel foglio main.c la variabile &#8216;int numero;&#8217; se volete utilizzarla nel foglio (facente sempre parte dello stesso progetto ovviamente) altro.c dovete dichiarla come &#8216;extern int numero;&#8217;, non potete di certo ri-dichiarla omettendo l&#8217;extern in tal caso il compilatore s&#8217;incazza e vi dice che è già stata dichiarata nel main.c, ovviamente io sto parlando solamente per variabili globali, di certo non per quelle locali. Comunque dato che è una cosa molto importante cercate di non dimenticarla: è veramente essenziale.



Contrariamente a extern, volatile è un&#8217;assegnazione molto meno usata (l&#8217;ho vista veramente di rado, molto rado). In pratica il qualificatore volatile segnala che l&#8217;oggetto può essere modificato dall&#8217;esterno.



Ora andiamo un po&#8217; più sul complesso per la parola chiave static, static si dichiara una variabile e questa dichiarazione può avere due funzioni, a seconda se si dichiara una variabile locale o globale, iniziamo da quella locale che è sicuramente la più semplice. Qui urge una spiegazione con codice, altrimenti non ci capite niente. Prendete per esempio la funzione:



void prova()

{

int x = 0;



x++;

}



Ogni qualvolta la funzione &#8216;prova&#8217; verrà chiamata, la variabile x verrà inzializzata a 0, quindi dopo l&#8217;incremento essa sarà sempre uguale a 1, prendiamo invece questa funzione:



void prova()

{

static int x = 0;



x++;

}



La prima volta che la funzione verrà chiamata la variabile è 0, ma nelle successive chiamate non viene più inizializzata, ciò fa si che x assuma a ogni chiamata della funzione un valore diverso. Se parliamo invece variabili globali, il discorso cambia alquanto, infatti in quel caso l&#8217;assegnazione di static viene usata per privatezza, poiché non è possibile accedere ad una variabile globale static attraverso un altro foglio nemmeno usando extern, ma non solo, funzioni nello stesso foglio possono usare una variabile static solo se viene dichiarata prima di esse, es:



void funzione1()

{

}



static int x;



void funzione2()

{

}



La funzione1 non potrà usare x, infatti questa variabile sarà solo accessibile a funzione2 e ovviamente alle altre funzioni dichiarate dopo funzione2, questo va da se.



Ora vediamo una parola usata molto raramente, si tratta di auto che fa parte delle classi di memorizzazione (come extern, register e static). La parola chiave auto sta solo a specificare il contrario di static per quanto riguarda le variabili locali, mentre static preserva la memoria, auto specifica che si riparte da capo, ma come potete intuire è una specificazione inutile, dato che le variabili locali sono per default auto, infatti:



void funzione()

{

int x = 0;

x++;

}



sarà equivalente a scrivere:



void funzione()

{

auto int x = 0;

x++;

}



infatti spesso i libri di c ansi la tralasciano addirittura, dicendo solamente che fa parte delle classi di memorizzazione.



Ok, adesso il peggio è passato, vedrete che le rimanenti parole sono molto più semplici da capire. Siamo quindi giunti a goto, è un&#8217;istruzione veramente banalissima, anche se poco usata: il c è un linguaggio strutturato e goto non è certo molto elegante. Probabilmente avete già conosciuto questa istruzione attraverso altri linguaggi. Mi sto dilungando troppo, un esempio vale più di cento parole:



void funzione()

{

goto fine;



printf(&#8220;\nCiao come va&#8221;);



fine: ; /* metto il ; perché non segue altra istruzione */

}



L&#8217;esempio è banale ma come forse avete intuito il messaghio &#8216;Ciao come va&#8217; non verrà mostrato, poiché il goto salta alla locazione &#8216;fine&#8217;, per indicare una locazione è sufficiente far seguire ad una parola i &#8216;:&#8217;. Dovreste aver capito, mi pare semplice.



Per quando riguarda sizeof, si comporta come una macro del compilatore, è molto semplice da spiegare, prendete per esempio la funzione malloc (già spiegata nel tutorial 2), essa serve per allocare bytes, ma se invece volessimo allocare variabili int? (e come ben saprete un int non corrisponde ad un byte). Bé allora possiamo sempre usare malloc e non calloc però dovremo usare sizeof poiché non possiamo supporre che il compilatore cosinderi un int come una dword, potrebbe anche non farlo&#8230;



Sarà quindi doveroso scrivere per l&#8217;allocazione:



pt = (int*)malloc(10 * sizeof(int));



scrivendo così noi allocheremo dieci int, potete usare sizeof sia con che senza parentesi, scrivere sizeof object è equivalente a scrivere sizeof(object).



Come certo ricorderete nel primo tutorial vi ho parlato di switch/case, prendete per esempio il ciclo:



switch(numero)

{

case 1: x = 5; break;

case 2: x = 3; breaK;

}



Ok ma facciamo a settare per x un valore nel caso si verifichi che il valore di switch non corrisponda ai vari case ? In questo caso si userà &#8216;default&#8217;, es:



switch(numero)

{

case 1: x = 5; break;

case 2: x = 3; breaK;



default: x = 0; break;

}



Affinché capiate meglio, traduco tutto in if/else:



if(numero == 1) x = 5;

else if(numero == 2) x = 3;

else x = 0;



Così forse risulta più comprensibile, il codice tradotto poi in linguaggio macchina risulterà essere lo stesso, ma questo non vi esonera affatto a usare switch, la leggibilità del codice è una cosa essenziale.



Sempre nel primo tutorial ho illustrato i cicli del c, abbiamo visto che per interrompere un ciclo è necessario usare break, es:



while(x < 10)

{

if((x = funzione()) == NULL) break; /* esce dal ciclo */

}



E fin qua tutto chiaro, ma se invece volessimo ritornare all&#8217;inizio del ciclo senza interromperlo? In questo caso bisogna usare continue, es:



for(x = 0; x < 10; x++)

{

printf(&#8220;\nHello&#8221;);

continue;

printf(&#8220; World&#8221;);

}



continue non interrompe il cliclo, semplicemente salta al prossimo turno se così si può dire.



Finalmente è terminato l&#8217;approfondimento, forse non avrete capito tutto subito, ma proseguendo col c, pian piano imparerete e potrete sempre fare riferimento a quello che ho spiegato.



Come promesso ora è giunto il momento di parlare di I/O, ovvero Input-Output. Per spiegare l&#8217;I/O sono stato piuttosto cauto, perché è un argomento con il quale è facile uscire dal c ansi (come spesso accade anche nei libri), il mio intento invece è di mantenermi più possibilmente sullo standard di modo che le conoscenze che aquisite siano indipendenti dall&#8217;os che utilizzate o dal compilatore.



I tutorial precedenti non erano proprio esenti dall&#8217;introdurre l&#8217;I/O, infatti voi conoscete già due funzioni che ne fanno parte: printf e scanf. Quasi tutte le funzioni ansi adibite all&#8217;I/O si trovano quindi nell&#8217;header stdio (standar IO). Oltre alle due funzioni che già conosciamo ve ne sono altre che sono più limitate ma che hanno una sintassi più semplice, es:



#include <stdio.h>



int main()

{

char str[30];



puts("Inserisci una stringa:");

gets(str);

puts("Hai inserito:");

puts(str);



return 0;

}



L&#8217;utilizzo di puts e gets come è possibile notare è circoscritto alle stringhe ed è molto meno flessibile di printf e scanf. Se invece è nostra intenzione lavorare con caratteri dovremo usare putchar e getchar. Analogamente a getchar vi è getch, che non visualizza i caratteri sullo schermo e non aspetta che l&#8217;utente prema invio per rendere i caratteri. Contrariamente a quello che molti pensano getch non è ansi, anche se è alquanto improbabile non trovare questa funzione generalmente dichiarata in conio.h, es:



#include <stdio.h>

#include <conio.h>



int main()

{

char c;



while((c = getch()) != '\r')

putchar(c);



return 0;

}



Nell&#8217;esempio c riceve il carattere premuto dall&#8217;utente e lo stampa con putchar, il ciclo viene interrotto se l&#8217;utente preme &#8216;invio&#8217;.



Prima di iniziare a parlare di flussi, vorrei introdurre una funzione che ha a che fare con le stringhe ma con sintassi simile a printf (infatti dichiarata in stdio), trattasi della funzione sprintf, questa funzione può immettere ciò che volete in una stringa, es:



#include <stdio.h>



int main()

{

char str[50];

int num;



scanf("%d", &num);

sprintf(str, "%Xh = %dd", num, num);

puts(str);



return 0;

}



Il risultato quindi che avremmo avuto su schermo tramite printf, lo avremo quindi nella stringa &#8216;str&#8217;. Capite bene che questa funzione è importantissiam e vi assicuro che la ritroverete spessissimo.



Well, accennato all&#8217;utilizzo di sprintf, direi di cominciare a spiegare le altre funzioni in I/O che però richiedono la specificazione del flusso (di input-output).



Prendiamo per esempio la funzione fprintf, la sintassi è:



fprintf(FILE *, const char *, ...);



Quindi è molto simile a quella di printf se non fosse per quel FILE *, inanzitutto FILE non è altro che una struttura che contiene informazioni riguardanti un file (ma questo lo vedremo dopo quando spiegherò il trattamento dei file) a noi basta sapere che questa come anche altre funzioni possono agire su dei flussi in I/O dichiarati nell&#8217;stdio, eccovi la tabella (flussi ansi eh):



nome - tipo &#8211; associazione



stdin Input Tastiera

stdout Output Schermo

stderr Errore Schermo



Quindi il seguente codice:



#include <stdio.h>



int main()

{



fprintf(stdout, "\nCiao");



return 0;

}



Non farà altro che stampare su schermo la parola &#8217;Ciao&#8217; come se avessi scritto printf(&#8220;\nCiao&#8221;);, lo stesso vale per la funzione fscanf solo che in questo caso il flusso dovrà essere stdin. Si aggiungono quindi le funzioni: fputs (come puts), fgets (come gets), getc e fgetc (come getchar) e putc e fputc (come putchar). Ma se si usano flussi ansi è comunque improbabile fare uso delle stesse funzioni che richiedono il flusso, quindi utilizzate a questa è veramente raro che le troviate. Non crediate che io abbia finito di commentare l&#8217;stdio.h, il quale ci riserva ancora diverse funzioni, le quali tuttavia vedremo man mano che si prosegue.



Visto che il tutorial non è ancora abbastanza lungo direi di introdurre il trattamento dei files, poiché abbiamo visto alcune funzioni che possono essere usate per il trattamento di essi (tutte le funzioni viste con argomento FILE). Come detto FILE non è altro che una struttura della quale non ci serve affatto conoscere i membri.



Partiamo dall&#8217;azione essenziale su di un file, aprirlo e chiuderlo:



#include <stdio.h>



int main()

{

FILE *File; /* handle file = puntatore a strutture FILE */



if((File = fopen("ciao.txt", "r")) == NULL)

printf("\nNon sono riuscito ad aprire il file");

else

{

printf("\nFile aperto");

fclose(File);

}



return 0;

}



Dunque andiamo per ordine, come prima cosa il programma tenta di aprire il file &#8216;ciao.txt&#8217;, se la funzione fopen (adibita appunto all&#8217;apertura di un file) ritorna valore uguale a 0, significa che non è stato possibile aprire il file, se invece il valore è diverso da 0, il file è stato apero e viene immediatamente richiuso tramite fclose.



Ma cosa significa quella &#8216;r&#8217; posta come secondo parametro di fopen? Semplicemente, specifica la modalità nella quale il file deve essere aperto, ecco una tabella con le modalità possibili:



Modalità &#8211; Spiegazione



r Apre in lettura.

w Apre il file in scrittura, nel caso che il file non esista,

esso viene creato, nel caso invece che il file già esista,

esso verrà cancellato e ne verrà creato uno nuovo.

a Apre il fine il aggiunta, se il file esiste i dati vengono

accodati al file esistente, se invece il file non esiste,

ne viene creato uno nuovo.

r+ Apre il file in lettura e scrittura, se il file esiste i dati

vengono sovrascritti, se invece non esiste ne viene creato uno

nuovo.

w+ Apre il file in scrittura e lettura, stessa regola come per r+.

a+ Apre il file in lettura e scrittura, se il file non esiste ne

creato uno nuovo, se invece esiste, i dati vengono accodati al

file esistente.

rb Apre il file in lettura binaria (vale la stessa regola di r).

wb Apre il file in scrittura binaria (stessa regola di w).

ab Apre il file in aggiunta binaria (stessa regola di a).

rb+ Stessa cosa di r+ in binario.

wb+ Stessa cosa di w+ in binario.

ab+ Stessa cosa di a+ in binario.



Se da un file volessimo leggere blocchi di memoria e scriverne dobbiamo usare le funzioni fread e fwrite, vediamo la sintassi:



int fread(void *buf, int size, int count, FILE *fpt);



buf è specifica il buffer che riceverà i byte letti (è void di modo che può specificare qualsiasi tipo di oggetto), size specifica la grandezza in byte dei singoli elementi da leggere, count specifica quanti sono gli elementi da leggere, fpt dovreste ormai averlo capito cosa è, il valore di ritorno specifica il numero di emelemnti letti. La funzione fwrite ha la stessa identica sintassi di fread quindi neanche sto a spiegarvela.



Fra poco capirete perché ho voluto impazientemente spiegarvi queste due funzioni.



Probabilmente vi sarete già domandati se vi sono nel c ansi funzioni per cancellare, rinominare e copiare files, dunque andiamo per ordine. Per cancellare un file vi è la funzione remove:



int remove(const char *name);



La funzione richiede solo un parametro, ovvero il nome del file da cancellare, se la funzione non ha successo il valore di ritorno sarà &#8211;1, altrimenti sarà 0. Per rinominare (muovere) un file invece vi è la funzione rename:



int rename(const char *source, const char *destination);



Gli argomenti della funzione sono l&#8217;origine e la destinazione del file, i valori di ritorno sono gli stessi di remove.



Ok, conosciamo le funzioni per cancellare e rinominare un file, ma se vi dicessi che l&#8217;ansi c non fornisce una funzione per copiarne? L&#8217;unica soluzione è di codarci una nostra routine. Spesso libri e guide forniscono una funzione del tipo: si prende un carattere dal file finché non si giunge al termine e lo si mette mette nel file di destinazione (rispettivamente fgetc e fputc) che come potete ben capire non è la soluzione più veloce di copiare carattere per carattere. Ho quindi opato per una funzione che leggesse blocchi e scrivesse blocchi il che sicuramente è più rapido come sistema.



#include <stdio.h>

#include <stdlib.h>



#define BUF_SIZE 4096



int fcopy(const char *, const char *);



int main()

{

char source[200], destination[200];



puts("Insericisci l'origine:");

scanf("%s", &source);

puts("Inserisci la destinazione:");

scanf("%s", &destination);



if(fcopy(source, destination) == 0)

puts("\nFile copiato");

else

puts("\nFile non copiato");



return 0;

}



int fcopy(const char *source, const char *destination)

{

FILE *fsource, *fdestination;

unsigned char *buffer;

int count;



if((fsource = fopen(source, "rb")) == NULL)

return -1;



if((fdestination = fopen(destination, "wb")) == NULL)

{

fclose(fsource);

return -1;

}



buffer = (unsigned char *)malloc(BUF_SIZE + 1);



if(buffer == NULL) return -1;



while((count = fread(buffer, sizeof(char),

BUF_SIZE, fsource)) != 0)

fwrite(buffer, sizeof(char), count, fdestination);



free(buffer);



fclose(fsource);

fclose(fdestination);



return 0;

}



Come vedete la funzione fcopy legge blocchi dal file di origine finché i byte letti risultano essere 0, i valori di ritono sono gli stessi di remove e rename.



Per concludere il tutorial ho pensato di spiegare le funzioni per file più importanti che ancora non abbiamo visto. Nella struttura FILE come ho già detto si trovano le informazioni riguardanti il file aperto e, ogni volta che leggiamo da questo file con funzioni come fread, fgetc ecc, il puntatore alla posizione corrente nel file viene incrementato in maniera direttamente proporzionale ai byte letti, se noi per esempio apriamo un file e usiamo una volta fgetc, la posizione corrente non sarà più il primo byte ma il secondo e ogni volta che fgetc viene richiamato ci troviamo un byte più in là. Ma se noi avessimo necessità di cambiare la posizione corrente nel file, come dovremmo fare? Semplice, vi sono funzioni adibite proprio a questo, partiamo da rewind:



void rewind(FILE *fpt);



La funzione rewind ricolloca la posizione corrente all&#8217;inizio del file, poi vi è fseek che permette di scegliere a noi dove puntare:



int fseek(FILE *fpt, long offset, int start_point);



fpt è il puntatore al file, offset specifica di quanti byte è necessario muoversi e start_point indica il punto di partenza dal quale muoversi, vi sono tre possibilità:



SEEK_CUR -> parte dalla posizione corrente all&#8217;interno del file.

SEEK_END -> parte dalla fine del file.

SEEK_SET -> parte dall&#8217;inizio del file.



Al contrario di fseek e rewind, la funzione ftell ci fa sapere la posizione corrente nel file, la sintassi è:



long ftell(FILE *fpt);



la funzione restituisce come valore di ritorno la posizione corrente in byte, se la funzione non ha successo il valore di ritorno sarà &#8211;1.



Una funzione ancora molto importante è feof, questa funzione se chiamata ci avverte (con una valore di ritorno = 0) se siamo giunti alla fine del corrente file, es:



#include <stdio.h>

#include <stdlib.h>



int main()

{

char FileName[200];

FILE *File;

unsigned long csum = 0;

int c;



puts("Insericisci il nome di un file:");

scanf("%s", &FileName);



if((File = fopen(FileName, "rb")) == NULL)

{

puts("\nFile non aperto");

return -1;

}



while(1)

{

c = fgetc(File);

if(feof(File)) break;

csum += c;

}



fclose(File);



printf("\n\nChecksum del file: %d\n", csum);



return 0;

}



In questo piccolo esempio viene aperto un file e ne vengono sommati tutti i byte ricavandoli con fgetc, una volta giunti alla fine del file il ciclo while si interrompe perché la funzione feof ritorna 0.



Ok, direi che per questa lezione può bastare, ovviamente non ho spiegato tutte le funzioni adibite ai file, ho offerto solo una panoramica sulle funzioni più importanti. Mi rendo conto che probabilmente questo tutorial sia stato un poco noioso, posso solo consigliarvi di cercare di capire le spiegazioni perché muniti di questi concetti potremo esplorare cose sicuramente più divertenti e interessanti. Inoltre prometto di non far trascorrere così tanto tempo come l&#8217;ultima volta, quindi preparatevi alla prossima lezione (niente anticipazioni).



Alla prossima.



Ntoskrnl

-------------------------------------------------------------------------------------



Links vari (alcuni tutorial in inglese) dai miei bookmarks:

http://www-math.unice.fr/laboratoire/he ... tutor.html (inglese, ottimo)

http://www.programmazione.it/index.php? ... 5&idArea=4 (ottimo, in Italiano)

http://www.cs.unibo.it/~casadei/FAD/c_cpp.html

http://www.termininformatici.com/progra ... /lezione01.
asp

Ciao! ;)

E buon lavoro!

LuVi
Top
  
 
 Oggetto del messaggio:
MessaggioInviato: mar mar 04, 2003 10:57 pm 
Quando hai fatto sposta nella sezione programmazione e cambiagli il titolo in "Tutorial C" ;)

LuVi
Top
  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 3:23 am 
Schiavo
Avatar utente
Iscritto il: mer feb 12, 2003 3:42 am
Messaggi: 161
Località: Roma
Se ti serve il compilatore fammi un fischio, dovrei avere ancora quello che ho usato qualche anno fa durante un corso...
I manuali li ho tutti su carta e fanno anche abbastanza schifo (produzioni IBM), a parte quelli su cui ho studiato e studio che sono marchiati McGrawHill!

Ok, fatta ricerchina... hai personale....
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 1:09 pm 
Schiavo
Avatar utente
Iscritto il: mar feb 25, 2003 12:42 pm
Messaggi: 1369
Località: seduto davanti al PC..dietro nn ci stò..:)
su html.it c'è un pò di roba...
_________________
ImmagineTHAT'S LIFE MAN, OUI C'EST LA VIE.
A volte è fragola ma spesso sa di merda.ImmagineFUCK THE SYSTEM!!!

SITO TARTARUGHE
Top
 Profilo E-mail Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 2:47 pm 
Onkillah ha scritto:
su html.it c'è un pò di roba...


Che cosa è caccaemmeelle?!?!?! :shock:
Top
  
 
 Oggetto del messaggio: Re: Aiutatemi!!!! Vi prego!!!!!
MessaggioInviato: mer mar 05, 2003 3:56 pm 
Schiavo
Avatar utente
Iscritto il: ven feb 07, 2003 6:46 pm
Messaggi: 501
Località: Milano
ninjathoo ha scritto:
Ragazzi!!!! Entro lunedì devo saper scrivere un programma su c!!!!
Ditemi se c'è qc opuscolo che mi permetta di farlo o qss cosa. L'importante che entro lunedì sappia mettere qcs su c.


Grazie.



P.S. C'è qcn che va al polimi?

Ora sono stanco! Vado a nanna. Mi aspetto migliaia di risposte per domani.


Grazie ancora.


P.S. Scusa Lucio se l'ho messo come importante, ma per me è vitale.


sono al secondo anno di ing delle tlc al polimi :wink:

tu cosa fai??

p.s.: ma informatica 1 non era al primo semestre??
_________________
fuck you, I won't do what you tell me!
Top
 Profilo E-mail Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 6:41 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
Per Lucio, grazie mille di tutto, molte cose sono proprio ql che ha spiegato la prof in aula ieri e credo che ce ne siano anche in più che non ho mai visto. (Se non l'hanno fatto, mi troverò avanti) :)


Per Kool, sono al primo anno di ing inf, si lo fanno nel 1° semestre, ma io oltre a studiare lavoro e così ho saltato il semestre per intero e ora sono nei casini. Considera anche che il mio diploma è di ragioneria :(


Ci si può vedere per bere un caffè insieme. Ho una K verde metallizzato e di solito vengo con ql. Ah!!! Vedi che ho anche una divisa dell'Atm, spesso infatti non risco neanche ad andare a casa a cambiarmi :)


Grazie a tutti.


Ciao, Giampj.
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 6:53 pm 
Schiavo
Avatar utente
Iscritto il: mer feb 12, 2003 3:42 am
Messaggi: 161
Località: Roma
ninjathoo ha scritto:
..................
Vedi che ho anche una divisa dell'Atm, spesso infatti non risco neanche ad andare a casa a cambiarmi :)
Grazie a tutti.
Ciao, Giampj.


Ma una volta gli studenti non lavoravano in birreria la sera??? :shock:

ATM= azienda trasporti metropolitani???

Il sogno della mia vita e' dare una bella scampanata con le "campane" dei vecchi tram di roma.. chissa' che un giorno non ci riesca!!! :D :D
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 7:11 pm 
Schiavo
Avatar utente
Iscritto il: ven feb 14, 2003 8:11 pm
Messaggi: 365
Località: Milano & Lunigiana
Miky71 ha scritto:

ATM= azienda trasporti metropolitani???


Azienda Trasporti Milanesi :vabe:
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 7:54 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
Miky71 ha scritto:
ninjathoo ha scritto:
..................
Vedi che ho anche una divisa dell'Atm, spesso infatti non risco neanche ad andare a casa a cambiarmi :)
Grazie a tutti.
Ciao, Giampj.


Ma una volta gli studenti non lavoravano in birreria la sera??? :shock:

ATM= azienda trasporti metropolitani???

Il sogno della mia vita e' dare una bella scampanata con le "campane" dei vecchi tram di roma.. chissa' che un giorno non ci riesca!!! :D :D
A me nella birreria non mi hanno voluto, hanno detto che loro le birre le dovevano vendere!!! :D :D :D
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 7:57 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
Fire ha scritto:
Miky71 ha scritto:

ATM= azienda trasporti metropolitani???


Azienda Trasporti Milanesi :vabe:
:shock: Che c'è? Anche tu di Mi l'avevo capito, ma Luni, dov'è?


P.S. So che il servizio non sempre soddisfa i passeggeri, ma qs succede + o - in tutti i settori!!!


:wink:
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 8:36 pm 
ninjathoo ha scritto:
Per Lucio, grazie mille di tutto, molte cose sono proprio ql che ha spiegato la prof in aula ieri e credo che ce ne siano anche in più che non ho mai visto. (Se non l'hanno fatto, mi troverò avanti) :)
Grazie a tutti.


Ciao, Giampj.


Allora ti levo il rilievo e sposto in programmazione. ;)

LuVi
Top
  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 9:47 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
Ok, grazie.

:wink:
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 9:52 pm 
Schiavo
Avatar utente
Iscritto il: ven feb 14, 2003 8:11 pm
Messaggi: 365
Località: Milano & Lunigiana
ninjathoo ha scritto:
Anche tu di Mi l'avevo capito, ma Luni, dov'è?


Lunigiana, una zona dell'alta Toscana.
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 9:55 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
Fire ha scritto:
ninjathoo ha scritto:
Anche tu di Mi l'avevo capito, ma Luni, dov'è?


Lunigiana, una zona dell'alta Toscana.
Scusa l'OT, ma come mai hai lasciato l'aria buona e il bel paesaggio per venire a MIlano?


Lavoro?
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: mer mar 05, 2003 11:12 pm 
Schiavo
Avatar utente
Iscritto il: ven feb 14, 2003 8:11 pm
Messaggi: 365
Località: Milano & Lunigiana
ninjathoo ha scritto:
Scusa l'OT, ma come mai hai lasciato l'aria buona e il bel paesaggio per venire a MIlano?
Lavoro?


E' qui dove mi guadagno il panettun..... :(
Scappo molto spesso dalla città, sto troppo bene al paesello :wink:
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: gio mar 06, 2003 2:22 pm 
Schiavo
Avatar utente
Iscritto il: gio gen 23, 2003 11:26 am
Messaggi: 5000
Località: Milano
Fire ha scritto:
ninjathoo ha scritto:
Scusa l'OT, ma come mai hai lasciato l'aria buona e il bel paesaggio per venire a MIlano?
Lavoro?


E' qui dove mi guadagno il panettun..... :(
Scappo molto spesso dalla città, sto troppo bene al paesello :wink:
Posta qc foto, che se ne vale la pena, ci vado qc volta nei w.e. Io sono stato a forte dei marmi. Conosci?
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: gio mar 06, 2003 4:35 pm 
Schiavo
Avatar utente
Iscritto il: ven feb 14, 2003 8:11 pm
Messaggi: 365
Località: Milano & Lunigiana
ninjathoo ha scritto:
Fire ha scritto:

Scappo molto spesso dalla città, sto troppo bene al paesello :wink:
Posta qc foto, che se ne vale la pena, ci vado qc volta nei w.e. Io sono stato a forte dei marmi. Conosci?


Conosco Forte dei Marmi, ma preferisco luoghi più tranquilli.
Fai una ricerca con Google, Lunigiana. Troverai parecchi suggerimenti per i tuoi Week-end.

Ciao
Top
 Profilo Non connesso  
 
 Oggetto del messaggio:
MessaggioInviato: ven mar 21, 2003 5:41 pm 
Schiavo
Avatar utente
Iscritto il: ven feb 07, 2003 6:46 pm
Messaggi: 501
Località: Milano
per il caffè io ci sono, basta che mi dici quando sei in univ...

ti rispondo solo adesso perchè mi ero completamente dimenticato di questo thread :P
_________________
fuck you, I won't do what you tell me!
Top
 Profilo E-mail Non connesso  
 
Visualizza ultimi messaggi:  Ordina per  
Apri un nuovo argomento Rispondi all’argomento  [ 23 messaggi ] 
-->

Tutti gli orari sono UTC +1 ora


Chi c’è in linea

Visitano il forum: Nessuno e 0 ospiti


Non puoi aprire nuovi argomenti
Non puoi rispondere negli argomenti
Non puoi modificare i tuoi messaggi
Non puoi cancellare i tuoi messaggi
Non puoi inviare allegati

Vai a:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Traduzione Italiana phpBB.it