<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://so.v2.cs.unibo.it/wiki/index.php?action=history&amp;feed=atom&amp;title=Stampf_-_implementazione_ridotta_della_printf.</id>
	<title>Stampf - implementazione ridotta della printf. - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://so.v2.cs.unibo.it/wiki/index.php?action=history&amp;feed=atom&amp;title=Stampf_-_implementazione_ridotta_della_printf."/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Stampf_-_implementazione_ridotta_della_printf.&amp;action=history"/>
	<updated>2026-05-05T22:15:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Stampf_-_implementazione_ridotta_della_printf.&amp;diff=187&amp;oldid=prev</id>
		<title>DaniC: Created page with &quot;&lt;syntaxhighlight lang=&quot;C&quot;&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;stdarg.h&gt;  char *itos(int n, int *p); //int to string (base 10) int slen(char *s); //string lenght...&quot;</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Stampf_-_implementazione_ridotta_della_printf.&amp;diff=187&amp;oldid=prev"/>
		<updated>2013-11-10T23:06:14Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; #include &amp;lt;stdlib.h&amp;gt; #include &amp;lt;unistd.h&amp;gt; #include &amp;lt;stdarg.h&amp;gt;  char *itos(int n, int *p); //int to string (base 10) int slen(char *s); //string lenght...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *itos(int n, int *p); //int to string (base 10)&lt;br /&gt;
int slen(char *s); //string lenght&lt;br /&gt;
char *itos0x(int n, int *p); //int to string (base 16)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * stampf funziona come la printf (viene invocata allo stesso modo) ma riconosce solo alcuni parametri (int, char, stringhe,  void * (qualsiasi puntatore) e il %)&lt;br /&gt;
 * ma non vengono fatti controlli sui tipi, impossibili con va_list che non è in grado di riconosce il tipo (infatti lo prende in input),&lt;br /&gt;
 * per cui se il tipo passato non corrisponde a quello indicato con %, si possono verificare errori a run time di vario tipo&lt;br /&gt;
 * per stampare usa la system call write&lt;br /&gt;
 */&lt;br /&gt;
void stampf(char* s, ...) {&lt;br /&gt;
	int i=0;&lt;br /&gt;
	va_list ap;&lt;br /&gt;
	va_start(ap,s);&lt;br /&gt;
	while (s[i]!='\0'){&lt;br /&gt;
		while (s[i]!='\0' &amp;amp;&amp;amp; s[i]!='%') i++; //raggiungo un % o la fine della stringa&lt;br /&gt;
		if (i&amp;gt;0) write( STDOUT_FILENO, s, i ); //stampo fino al punto raggiunto, escludendo l'eventuale % o \0&lt;br /&gt;
		if (s[i]=='%') {&lt;br /&gt;
			//var temporanee che non è detto vengano utilizzate&lt;br /&gt;
			int n; //usato per i parametri interi, per gli indirizzi e per contenere il num di carattere delle conversioni di questi in stringhe&lt;br /&gt;
			char *str; //usato per le stringhe di cui sopra e per quelle passate come parametro&lt;br /&gt;
			char c[6]=&amp;quot;(nil)&amp;quot;; //nil già pronto (come usa printf) per i puntatori NULL, altrimenti c[0] viene usato per i parametri carattere&lt;br /&gt;
			switch(s[++i]){&lt;br /&gt;
				case 'd':&lt;br /&gt;
					n=va_arg(ap,int);&lt;br /&gt;
					str=itos(n,&amp;amp;n);&lt;br /&gt;
					write(STDOUT_FILENO, str, n );&lt;br /&gt;
					free(str);&lt;br /&gt;
					break;&lt;br /&gt;
				case 's':&lt;br /&gt;
					str=va_arg(ap,char*);&lt;br /&gt;
					write(STDOUT_FILENO, str, slen(str) );&lt;br /&gt;
					break;&lt;br /&gt;
				case 'c':&lt;br /&gt;
					c[0]=va_arg(ap,int); //int perchè va_arg converte i caratteri in interi prima di restituirli&lt;br /&gt;
					write(STDOUT_FILENO, &amp;amp;c[0], 1 );&lt;br /&gt;
					break;&lt;br /&gt;
				case 'p':&lt;br /&gt;
					n=(int)va_arg(ap,void*);&lt;br /&gt;
					if (n==0) write(STDOUT_FILENO, c, 5 ); //stampo (nil)&lt;br /&gt;
					else {&lt;br /&gt;
						str=itos0x(n,&amp;amp;n);&lt;br /&gt;
						write(STDOUT_FILENO, str, n );&lt;br /&gt;
						free(str);&lt;br /&gt;
					}&lt;br /&gt;
					break;&lt;br /&gt;
				case '%':&lt;br /&gt;
					write(STDOUT_FILENO, &amp;amp;s[i], 1 );&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			i++;&lt;br /&gt;
		}&lt;br /&gt;
		s=s+i; //faccio ricominciare la lettura di s o dal carattere successivo a quello dopo il % o dal '\0' e in quest'ultimo caso si uscirà dal ciclo&lt;br /&gt;
		i=0;&lt;br /&gt;
	}&lt;br /&gt;
	va_end(ap);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * itos converte un intero in una stringa allocata dinamicamente&lt;br /&gt;
 * prende in input il numero e un indirizzo (anche null) usato per restituire il numero di caratteri escluso lo '\0' &lt;br /&gt;
 */&lt;br /&gt;
char *itos(int n, int *p) {&lt;br /&gt;
	int ncar=1,tmp=n/10,i,inizio=0;&lt;br /&gt;
	char *s=NULL;&lt;br /&gt;
	while (tmp) { //conto le cifre di n&lt;br /&gt;
		ncar++;&lt;br /&gt;
		tmp/=10;&lt;br /&gt;
	}&lt;br /&gt;
	if (n&amp;lt;0) { //metto il segno&lt;br /&gt;
		ncar++;&lt;br /&gt;
		s=(char*)malloc((ncar+1)*sizeof(char)); //+1 per il carattere terminatore&lt;br /&gt;
		*s='-';&lt;br /&gt;
		inizio=1;&lt;br /&gt;
		n*=-1;&lt;br /&gt;
	}&lt;br /&gt;
	else s=(char*)malloc((ncar+1)*sizeof(char));&lt;br /&gt;
	s[ncar]='\0';&lt;br /&gt;
	for (i=ncar-1; i&amp;gt;=inizio; n/=10, i--) s[i]=(char)(n%10 + 48); //converto la cifra in carattere ascii, 48 è lo zero&lt;br /&gt;
	if (p) *p=ncar;&lt;br /&gt;
	return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * itos0x converte un intero in num esadecimale e lo restituisce come stringa allocata dinamicamente&lt;br /&gt;
 * prende in input il numero e un indirizzo (anche null) usato per restituire il numero di caratteri escluso lo '\0' &lt;br /&gt;
 */&lt;br /&gt;
char *itos0x(int n, int *p){&lt;br /&gt;
	int ncar=0, i,tmp,j;&lt;br /&gt;
	char v[sizeof(int *)*2]; //con un num esadecimale di 2 cifre posso rappresentare un byte, quindi per rappresentarne sizeof(int*) mi servirà al max un vettore grande il doppio&lt;br /&gt;
	char *s; //stringa in output&lt;br /&gt;
	do { //converto il num in esadecimale&lt;br /&gt;
		tmp=n%16;&lt;br /&gt;
		if (tmp&amp;lt;10) v[ncar]=tmp+48;&lt;br /&gt;
		else v[ncar]=tmp-10 + 97; //97 è la a minuscola nella tab ascii&lt;br /&gt;
		n/=16;&lt;br /&gt;
		ncar++;&lt;br /&gt;
	}while (n);&lt;br /&gt;
	s=(char*)malloc((ncar+3)*sizeof(char)); //+3 per il 0x iniziale e lo '\0' finale&lt;br /&gt;
	s[0]='0';&lt;br /&gt;
	s[1]='x';&lt;br /&gt;
	for (i=2, j=ncar-1; i&amp;lt;ncar+2; i++, j--) s[i]=v[j]; //copio v in s in ordine inverso&lt;br /&gt;
	s[i]='\0';&lt;br /&gt;
	if (p) *p=ncar+2;&lt;br /&gt;
	return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * slen restituisce la lunghezza di una stringa escluso lo '\0'&lt;br /&gt;
 */&lt;br /&gt;
int slen(char *s) {&lt;br /&gt;
	int l=0;&lt;br /&gt;
	while (*s++) l++;&lt;br /&gt;
	return l;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Daniele Cortesi&lt;/div&gt;</summary>
		<author><name>DaniC</name></author>
	</entry>
</feed>