Newsgroup: it.comp.lang.c
Titolo: itob

Ho provato a risolvere l'esercizio 3-5 del k&r
"Scrivere una funzione itob(n,s,b) che converte l'intero n nella
corrispondente sequenza di caratteri in base b, e mette in s la
stringa risultante."
Vorrei sapere, se possibile, se itob è portabile o se ci sono errori.
Ok itob funziona solo con caratteri ascii, quello che vorrei sapere se
funziona anche se varia la "wordsize" (il numero di bit utili per
rappresentare int) o la sua rappresentazione 
 nei diversi elaboratori.
#include <stdio.h>
void getint( FILE* f, int* i)
{while( fscanf(f,"%d", i) != 1 ) 
              {fprintf(stderr , "Errore> ");
               while(getc(f)!='\n');
              }
}
int strlen(char s[])
{int i;
 for(i=0;s[i]!='\0';++i);
 return i;
}
void reverse(char s[])
{int i, j;
 char temp;
 for(i=0,j=strlen(s)-1;i<j; ++i,--j)
  {temp=s[i]; s[i]=s[j]; s[j]=temp;}
}
int itob(int n, char s[], int b)
{int i=0, sign=1, x;
 unsigned y;
 s[0]='\0';
 if(b>35 || b<2 ) return -1;
 if( n<0 && b==10) {y=-n; sign=-1;}
 else y= n;
 do{ x=y%b;
       s[i++]=(char) (x + ((x>=0 && x<=9) ? '0' : 'a'-10));
      }while((y/=b)>0);
 if(b==16) s[i++]='x';
 if(b==16 || b==8) s[i++]='0';
 if(sign<0) s[i++]='-';
 s[i]='\0';
 reverse(s);
 return 0;
}
 main()
{int ch, n, g;
 char s[80];
do{
  printf("\nInserisci due interi: numero e base:(\"1 2\" termina)>");
   do{getint(stdin, &n);
      getint(stdin, &g);
      printf("\nPartenza=%d", n);
      if( ! itob(n,s,g) )printf("\nArrivo  =%s ", s );
      else printf("\nErrore di base");
      if((ch=fgetc(stdin) )=='\n') break;
      else ungetc(ch,stdin);
      } while(ch!=EOF);
   }while(n != 1);
return 0;
}

 return 0;
</CODE>
Per il resto mi pare portabile.
Mox :)

} while (condizione)
nel codice di funzioni mi piace incolonnare le parentesi
corrispondenti tra di loro per esempio:
do{  bla bla bla
       bla bla bla
     } while (condizione)
nel mio news-reader le parentesi graffe sono incolonnate
ancora grazie
In altre parole tu dici che cosě va meglio:
#include <stdio.h>
void getint( FILE* f, int* i)
{while( fscanf(f,"%d", i) != 1 ) 
              {fprintf(stderr , "Errore> ");
               while(getc(f)!='\n');
              }
}
int strlen(char s[])
{int i;
 for(i=0;s[i]!='\0';++i);
 return i;
}
void reverse(char s[])
{int i, j;
 char temp;
 for(i=0,j=strlen(s)-1;i<j; ++i,--j)
  {temp=s[i]; s[i]=s[j]; s[j]=temp;}
}
int itob(int n, char s[], int b)
{int i=0, sign=1;
 char x[]="0123456789abcdefghijklmnopqrstuvwxyz";
 unsigned y;
 s[0]='\0';
 if(b>36 || b<2 ) return -1;
 if( n<0 && b==10) {y=-n; sign=-1;}
 else y= n;
 do{
    s[i++]=x[y%b];
   }while((y/=b)>0);
 if(b==16) s[i++]='x';
 if(b==16 || b==8) s[i++]='0';
 if(sign<0) s[i++]='-';
 s[i]='\0';
 reverse(s);
 return i;
}
 main()
{int ch, n, g;
 char s[80];
do{printf("\nInserisci due interi: numero e base:(\"1 2 \"
termina)>");
   do{getint(stdin, &n);
      getint(stdin, &g);
      printf("\nPartenza=%d", n);
      if(n <10e+50 && n>(-10e+50))
        (itob(n,s,g)==-1) ? printf("\nErrore di base"):
                                         printf("\nArrivo  =%s ", s );
      else printf("\nNumero troppo grande");
      if((ch=fgetc(stdin) )=='\n') break;
      else ungetc(ch,stdin);
      } while(ch!=EOF);
 }while(n != 1);
return 0;
}
Saluti e Buon Anno a tutti

    s[i++]=x[y%b];
Che e' equivalente, per come il C gestisce le string literal (mi pare
sia il nome giusto, se no cazziatemi pure :P ) a:
<CODE>
s[i++] = "0123456789abcdefghijklmnopqrstuvwxyz"[y%b];
</CODE>
Mox :)