Newsgroup: it.comp.lang.c
Titolo: [HELP]minuscole--->MAIUSCOLE

Ciao a tutti di nuovo e scusate se vi disturbo coi proleblemi da
principiante. Devo scrivere un programma che apra un file di testo esistente
e ne copi il contenuto in un secondo file di testo, mettendo in maiuscolo le
lettere in minuscolo. Ora, per l'operazione di copia non ci sono problemi. E
la conversione minuscolo--->MAIUSCOLO che non riesco ad eseguire. Potreste
aiutarmi?
Grazie mille!

Roberto,
Roberto wrote:

<code>
	#include <stdio.h>
	#include <ctype.h>
	int
	main(void)
	{
		/*
		 * Copies characters from standard input to
		 * standard output, converting lower case to upper.
		 */
		int ch;
		while((ch=getc())!=EOF)	putc(toupper(ch));
		return 0;
	}
</code>
--
Alla prossima,
Marco

 ha scritto nel messaggio
news:3B408E59...@bar.va...


 riesco ad eseguire. 
toupper, tolower - convert letter to upper or lower case
SYNOPSIS
       #include <ctype.h>
       int toupper (int c);
       int tolower (int c);
DESCRIPTION
       toupper() converts the letter c to upper case, if possible.
       tolower() converts the letter c to lower case, if possible.
       If  c is not an unsigned char value, or EOF, the behaviour of
       these functions is undefined.
RETURN VALUE
       The value returned is that of the converted letter, or c  if 
       the conversion was not possible.

 Grazie mille Marco, ma cosa è toupper?
Prova ad indovinare ...
E' una funzione di ctype.h :
int toupper(int c)
che converte c in una letter maiuscola, come dice il nome to-upper-case
(upper-case=maiuscolo).
Alex

 aiutarmi?
Se ti interessa anche un implementazione di una possibile funzione che
esegue la conversione richiesta :
int Mtoupper(int ch)
{
    return ch & 0xffffffdf;        //return ch - 32
}
che equivale a (ch - 32) poichè tra una minuscola e una maiscola c'è una
differenza di 32 (2^5).
Da notare che comunque che questa canversione non è portabile in un sistema
con differente codici per i caratteri.

 con differente codici per i caratteri.
   E non solo, cosa accadrebbe con parametri che non sono caratteri 
alfabetici? Il punto di forza della toupper() vera e` proprio che e` in 
grado di discernere cosa "maiuscolizzare" o meno. Demandare il controllo 
al programmatore fa *estremamente* Microsoft e, conseguentemente, e` *male*.
--
Alla prossima,
Marco


Ragionamento ineccepibile.
Allora cosě forse va meglio :
int Mtoupper(int ch)
{
 if(isalpha(ch))
      return ch & 0xffffffdf;
 return ch;
}

 con differente codici per i caratteri.
Non ho ben chiaro quale influenza questo possa avere nel caso specifico,
però io farei anche attenzione all'implicita assunzione che fai che un
int sia di 32 bit.
EMG

 ha scritto nel messaggio
news:3B40C047...@flashnet.it...


 }
   Prova questa: secondo l'assunto che i caratteri alfabetici sono 
lessicograficamente contigui (e nelle due grandi famigli ASCII ed EBCDIC 
lo sono), dovrebbe addirittura essere portabile.
<code>
	/*
	 * my_to_upper.c -- Poor formed version of the ISO
	 *                  toupper() function.
	 */
	static int TRANSCODE[]={
		'A','B','C','D','E','F','G','H','I','J','K','L','M',
		'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
	};
	int
	my_to_upper(int ch)
	{
		int ndx=ch-'a';
		if((ndx<0)||(ndx>25))	return ch;
		else			return TRANSCODE[ndx];


  }
Scusa, ma per essere portabile con "ASCII ed EBCDIC" non bastava:
int my_toupper(int c)
{
    if((c>='a')&&(c<='z'))
        c-='a'-'A';
    return c;
}
No ?!?
Forse, visto che tu usi un array con tutte le lettere maiuscole (ed anche
una variabile intera all'interno della funzione), mi e' sfuggito qualche
cosa, ma davvero non so che cosa, fammi sapere ...
Alex

 cosa, ma davvero non so che cosa, fammi sapere ...
   No, perche` i codici EBCDIC delle lettere minuscole sono inferiori a 
quelli delle lettere maiuscole, al contrario di quanto accade nella 
codifica ASCII. Con la tabella di /look-up/, invece, si dovrebbe essere 
al riparo.
--
Alla prossima,
Marco

 al riparo.
   Dimentica il paragrafo superiore... :)
-- 
Alla prossima,
Marco

    Dimentica il paragrafo superiore... :)
Ok, non ti preoccupare, capitano spessissimo anche a me queste cose ;-)
L'avevo tenuto a mente (il fatto da de menzionato) e che quindi qualche
codifica potesse avere "questa differenza".
E' vero che 'a'-'A' in tale caso risulta negativo, ma cio' conduce
ugualmente al risultato voluto.
In conclusione confermi che il mio codice e portabile almeno su questi due
sistemi ?
Alex

Alex
Un consiglio: su internet trovi gente che dice cose vere e
gente che parla per far prendere aria ai denti.
Il codice di cui state parlando non e' portabile perche' sono
false le premesse su cui si fonda (i caratteri alfabetici
NON sono contigui in EBCDIC indipendentemente da cosa ne pensa
Marco Nantoni). Se non credi a quanto dico (e fai bene a non
fidarti di principio) basta che ti fai una ricerca in
internet e controlli tu stesso.
Trust no one ;)
Andrea
PS:
  Se quelli del comitato di standardizzazione del C hanno
  deciso che sarebbe stato molto utile avere delle funzioni
  specifiche come isalpha() o toupper() un motivo ci sara'
  anche stato no ?
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

lo sono), dovrebbe addirittura essere portabile.
In EBCDIC le lettere dell'alfabeto non sono *affatto* contigue:
  'a'...'i' = 0x81...0x89
  'j'...'r' = 0x91...0x99
  's'...'z' = 0xA2...0xA9
  'A'...'I' = 0xC1...0xC9
  'J'...'R' = 0xD1...0xD9
  'S'...'Z' = 0xE2...0xE9
  '0'...'9' = 0xF0...0xF9
Andrea
PS:
  Ma costa cosi' tanto fare qualche indagine prima di
  sparare cretinate in un newsgroup ??


   anche stato no ?
Su questo non ci piove ....
Non tentavo di trovare un sostituto a queste funzioni, stavo solo al gioco e
postavo anche il mio codice...
Ho solo presentato il codice in oggetto in quanto le soluzioni presentate
non mi sembravano soddisfacenti.
Ovvio che avendo a disposizione la funzione toupper() non userei mai una
funzione fatta in prima persona ;-)
In pratica non ho seguito il post fin dall'inizio, ma ho incominciato a
seguirlo vedendo una serie di rimpalli tra iGor e Marco Natoni...che si
concludeva con un programma a mio avviso un tantino sprecato. Di conseguenza
ho letto le specifiche:
<QUOTE MARCO>
Prova questa: secondo l'assunto che i caratteri alfabetici sono
lessicograficamente contigui (e nelle due grandi famigli ASCII ed EBCDIC
lo sono), dovrebbe addirittura essere portabile.
</QUOTE>
e basandomi solo su queste (dandole per vere ;-) ho implementato il codice
che a questo punto (oltre che essere inutile come gia' sapevo) e' anche non
funzionante su EBCDIC.
(o meglio trasforma in maiuscolo le lettere, visto che la differenza e'
sempre la stessa, ma non tiene in considerazione i caratteri in mezzo che
verrebbero, senza successo, trasformati in "maiuscolo" (di fatto dando
risultati senza senso)).
Grazie per l'appunto, ora so anche qualche cosa su questo set di caratteri
che non ho mai avuto il "piacere" di utilizzare.... (non che ci tenga...)
Alex

   '0'...'9' = 0xF0...0xF9
non capisco cosa intendi: e' vero che non sono contigui, ma la distanza 
tra le due serie e' costante, per avere codice portabile ASCII - EBCDIC 
basta una cosa del tipo
char my_toupper(char c){
  if (islower(c))
     return c + (`A` - `a`); 
   return c;
}

   '0'...'9' = 0xF0...0xF9
non capisco cosa intendi: e' vero che non sono contigui, ma la distanza 
tra le due serie e' costante, per avere codice portabile ASCII - EBCDIC 
basta una cosa del tipo
char my_toupper(char c){
  if (islower(c))
     return c + (`A` - `a`); 
   return c;
}
Ovviamente concordo sul cercare conferme di cio' che si dice...

Ovviamente concordo sul cercare conferme di cio' che si dice...
Questa e' la cosa piu' importante :)
Andrea


   if (islower(c))
 per stare al gioco ovviamente non usi alcuna funzione standard.
Se usi islower() perche' mai non utilizzare toupper ?!?
Il gioco consisteva nel fare finta che tutte quelle funzioni non esistessero
...
Alex

 portabili.
bhe', semplice:
char my_toupper(char c){
  if (my_islower(c))
     return c + (`A` - `a`); 
   return c;
}
:)

 }
va bene, va bene, per una volta non faccio il pigro (sara' che non ho 
nulla di meglio da fare, e fa un caldo bestia per uscire...)
int my_islower(char c){
  switch(c){
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
    case 'g':
    case 'h':
    case 'i':
    case 'j':
    case 'k':
    case 'l':
    case 'm':
    case 'n':
    case 'o':
    case 'p':
    case 'q':
    case 'r':
    case 's':
    case 't':
    case 'u':
    case 'v':
    case 'w':
    case 'x':
    case 'y':
    case 'z':
      return 1;
    default:
      return 0;
  }
}

 ha scritto

A questo punto my_toupper poteva anche essere strutturata in questo modo:
case 'a':
    return 'A';
case 'b':
    return 'B';
Eravamo tutti in grado di fare questo, ma volevamo fortemente evitarlo ;-)
Quello che fai tu case 'a': case 'b': .... case 'z': return c-('a'-'A'); e'
piu' breve visto che la distanza sembra rimanere la stesa, ma la verita' e'
che abbiamo perso tempo e lo sapevamo, abbiamo lavorato su specifiche
sbagliate (e non lo sapevamo) ora basta, il gioco e' finito ;-)
Alex
P.S. quando metti 10000 case, che devono eseguire lo stesso codice,
raggruppane 3-4 su di una unica riga, altrimenti il codice sembra uno
spaghetto in verticale ;-)

 spaghetto in verticale ;-)
e la leggibilita'?
switch(numero) {
 case 34872348:
 case 54873049:
 case 44965:
 case 7597846:
 case 0x3421343:
 case 041:
 do_pizza_e_fichi(numero);
 
 default: break;
}
e' piu' leggibile di
switch(numero) {
 case 34872348: case 54873049:   case 44965:
 case 7597846:  case 0x3421343:  case 041:
 do_pizza_e_fichi(numero);
 
 default: break;
}
non trovi?

 e la leggibilita'?
Ma quale leggibilita' !?! Ma smettila !
case 'a': case 'b': case 'c': case 'd':
case 'e': case 'f': case 'g': case 'h':
Ohhhh!?! Non riesci a leggerlo ?!?
Beh, io invece mi stanco di piu' a leggere un mucchio di righe con una sola
istruzione.
Ad ogni modo e' questione di gusti, tanto e' vero che lo avevo scritto come
P.S. !
Alex
P.S. un messaggio per parlarmi di riutilizzo di una funzione che non si
utilizzera' mai (fraintendendomi) e di leggibilita' del codice ?!? Mah....

 Mah....
si, perche' quando si programma, sia pure un WORM, e' meglio avere 
certi concetti "a prescindere": poi diventano abitudine, e migliori il 
modo di scrivere il tuo codice.

}
Questa versione non e' compatibile con lo standard C
(manca la gestione EOF)
Come ultima cosa ti riporto un commento presente nel
file di include ctype.h distribuito assieme al gcc:
/* These are defined in ctype-info.c.
   The declarations here must match those in
   localeinfo.h. These point into arrays of 384, so
   they can be indexed by any `unsigned char' value
   [0,255]; by EOF (-1); or by any `signed char'
   value [-128,-1).
   ISO C requires that the ctype functions work for
   `unsigned char' values and for EOF; we also
   support negative `signed char' values for broken
   old programs. The case conversion arrays are of
   `int's rather than `unsigned char's because
   tolower (EOF) must be EOF, which doesn't fit into
   an `unsigned char'.
   But today more important is that the arrays are
   also used for multi-byte character sets.  */
Il riferimento a "broken old programs" e' a codice C
pre-standard che assume di poter passare anche char
negativi alle funzioni dichiarate in <ctype.h>.
HTH


 questo insieme significa scrivere codice *non portabile*.
ho capito. la  soluzione alla questione e' facile, una volta che se ne 
conoscono i termini esatti.
una curiosita': il testo del C99 si trova on-line o solo in libreria? o 
per niente?