Newsgroup: it.comp.lang.c++
Titolo: codifica/decodifica ROT13

salve a tutti, ho un problema con un banalissimo programmino di codifica/
decodifica ROT13.
l'algoritmo è decisamente banale da implementare, ma ho dei comportamenti
strani per caratteri superiori al codice ascii 115 (s), e non riesco
assolutamente a capire perché!
sarà sicuramente una stupidissima svista, ma non riesco ad individuare l'
errore.. ecco il codice: (definire debug per gli output dei codici ascii)
/*rot13.cpp
  codifica e decodifica in rot13*/
#include <iostream>
#include <string>
#include <cctype>
#include <climits>
using namespace std;
void code(char&);
int main() {
    string input;
    cout << "Inserire frase da codificare/decodificare: ";
    getline(cin, input);
    for(string::iterator iter = input.begin(); iter != input.end(); ++iter)
{
        if(isalpha(*iter))
            code(*iter);
    }
    cout << "Risultato: " << input << endl;
    while(cin.get() != '\n');
    return 0;
}
void code(char &a) {
    #ifdef debug
    cout << "vecchio ascii: " << static_cast<int>(a) << endl;
    #endif
    int min, max;
    if(islower(a)) {
        min = 97;        /*estremi ASCII delle lettere minuscole*/
        max = 122;
    }
    else {
        min = 65;        /*estremi ASCII delle lettere maiuscole*/
        max = 90;
    }
    a += 13;
    if(a < min)        /*se si va oltre i limiti, rientrare nel range*/
        a += 26;
    if(a > max)
        a -= 26;
    #ifdef debug
    cout << "nuovo ascii: " << static_cast<int>(a) << endl;
    #endif
}
grazie mille in anticipo a chi riuscirà ad essermi d'aiuto. :)

 void code(char &a) {
void code(unsigned char &a) {
in pratica... andavi in overflow sui char :-))
ciao
--
Gerolamo

 in pratica... andavi in overflow sui char :-))
mm..
ora provo le modifiche che mi hai suggerito, grazie!
ma non ho capito l'errore.. puoi spiegarmi qual'č?
grazie ancora!!

 grazie ancora!!
Gli 'unsigned char', se sono a 8 bit come su buona parte
delle architetture esistenti, rappresentano un numero
che va da 0 (0000 0000) a 255(1111 1111).
I 'signed char', invece hanno un range che va da
-127 a 127, poichè utilizzano il primo bit come bit di segno.
Il significato di un char è, generalmente, dato dalla tabella
ASCII,  es. 97='a', 122='z', ...
Ora considera il carattere 'i' = 105.
Quando lo inserisci nel tuo codice le operazioni sono:
min = 97;
max = 122;
a += 13; // i => 118
poi controlli che 97 <= 118 <= 122
e quindi non fai nulla e restituisci 118 == 'v'
che è il valore che scrivi a schermo.
A questo punto proviamo a reinserire nel tuo algoritmo la
lettera 'v':
min = 97;
max = 122;
a += 13; // v => 118 + 13 == 131
ma 131 è fuori dal range dei 'signed char' !!!
quindi, a causa dell'overflow succede questo:
118 = 0111 0110 in binario
13 = 0000 1101
131 = 1000 0011
ma 1000 0011 per un signed char è un numero negativo,
che vale -125
A questo punto tu controlli che
-125 < 97 e fai a+=26
per cui il tuo valore, adesso, è -99, che è il valore che
stampi come risultato.
Errato.
Usando gli 'unsigned char' non hai questo problema di
overflow e quindi il tuo algoritmo è giusto.
ciao
--
Gerolamo

-127 a 127, poichè utilizzano il primo bit come bit di segno.
In complemento a due vanno da -128 a 127 (128 negativi, 127 positivi,
1 zero).
-- 
Marco Barisione (ICQ 84277092)

 127 positivi, 1 zero).
Hai ragione, mi è scappato :-))
--
Gerolamo

 ciao
Grazie mille, sei stato davvero chiarissimo nella tua spiegazione.