PDA

View Full Version : [C] Problema con programma ciphertext


Filly95
19-11-2011, 23:43
Salve a tutti, in questi giorni mi sto allenando per le prossime olimpiadi di informatica usando i vecchi quesiti delle precedenti edizioni. In particolare uno mi ha stuzzicato e vorrei riscriverlo distaccandomi dalla soluzione inclusa nei file del quesito.

Quesito:
Due ragazzi comunicano tra di loro usando un codice particolare, in cui ogni lettera che si intende comunicare in realtà è rappresentata dalla successiva in ordine alfabetico. Per esempio B=C e P=Q. Allo stesso modo le vocali: A=E e O=U. Nei casi delle ultime consonanti/vocali dell'alfabeto, esse sono rappresentate dalle prime. Esempio: Z=B e Y=A (Y è considerata vocale). La punteggiatura (compresi accenti e apostrofi) rimane invariata.
Scrivere un programma in C che rispetti le regole scritte sopra e, acquisendo un input da tastiera, restituisca il messaggio "criptato". (In teoria l'esercizio chiede anche che sia case-sensitive e che le regole vengano applicate anche ai numeri, ma quello ci penserò dopo...)

Volevo evitare di farlo con una sequenza lunghissima di case, quindi ho pensato di farlo sfruttando degli array. Ecco il mio elaborato: http://ideone.com/xzgMw


Ho provato a compilarlo con Dev-C++ ma m dà errore (ma li spiega da cane), mentre ideone li spiega un po' meglio, ma nonostante questo non riesco a capire. Come posso fare? Come approccio è giusto o sbaglio anche quello? Grazie a tutti quelli che risponderanno!

GByTe87
20-11-2011, 10:20
Quelli segnalati li sono errori abbastanza banali, del tipo manca un punto e virgola (prog.c:26: error: expected ‘;’ before ‘k’) o c'è un & di troppo (scanf("%s", &msg); ).

Io lo farei in modo diverso, più efficiente; i cicli annidati non sono proprio il max, da questo punto di vista.. suggerimento: click! (http://www.pluto.it/files/ildp/man/man7/ascii.7.html)

ndakota
20-11-2011, 10:24
Qualche errore logico o di linguaggio

1)


alfabeto[j+1] = msg_criptato[k]


Manca il ';'. Inoltre, volevi fare il contrario


msg_criptato[k] = alfabeto[j+1];


2)


for(k=0; k<80; k++) {
printf("Il messaggio criptato è: %s", msg_criptato[80]); //Stampo il messaggio criptato
}


Una stringa la stampi direttamente, non c'è bisogno di un ciclo. Un conto è se stampi carattere per carattere ma tu stampi la stringa.


printf("Il messaggio criptato è: %s", msg_criptato);


Notare che stampavi sempre l'81-esimo elemento del tuo array di char che nel tuo caso sarebbe dovuto essere il terminatore di stringa.

3) I commenti sono quasi tutti inutili. Addirittura un commento


// auto esplicativo


? Perdo tempo a leggerlo e non mi aggiunge nulla :D

ndakota
20-11-2011, 10:25
Quelli segnalati li sono errori abbastanza banali, del tipo manca un punto e virgola (prog.c:26: error: expected ‘;’ before ‘k’) o c'è un & di troppo (scanf("%s", &msg); ).

Io lo farei in modo diverso, più efficiente; i cicli annidati non sono proprio il max, da questo punto di vista.. suggerimento: click! (http://www.pluto.it/files/ildp/man/man7/ascii.7.html)

L'& non è di troppo ma è semplicemente inutile. Verrà visto come puntatore al primo elemento in ogni caso.

GByTe87
20-11-2011, 10:36
L'& non è di troppo ma è semplicemente inutile. Verrà visto come puntatore al primo elemento in ogni caso.

Vero anche questo; potrebbe però essere un indizio del fatto che non si conosce appieno la dualità pointer/array, cosa che nel C porta a drammi, sconfitte, imprecazioni contro gli dei, ore di straordinario non retribuito. :D

ndakota
20-11-2011, 13:09
In effetti il ragazzo mostra carenze nella conoscenza del linguaggio C. Il mio consiglio è magari di farlo in Java, dove alcuni di questi problemi non sussistono. Altrimenti, studiarsi C per bene.

Filly95
20-11-2011, 15:36
Quelli segnalati li sono errori abbastanza banali, del tipo manca un punto e virgola (prog.c:26: error: expected ‘;’ before ‘k’) o c'è un & di troppo (scanf("%s", &msg); ).

Io lo farei in modo diverso, più efficiente; i cicli annidati non sono proprio il max, da questo punto di vista.. suggerimento: click! (http://www.pluto.it/files/ildp/man/man7/ascii.7.html)

Mi ero accorto di quel punto e virgola, l'ho corretto ma ho uploadato la versione senza...
Avevo pensato all'ASCII ma non saprei come implementarlo nel programma; cioè, se io gli do direttamente un hex lui sa già di che carattere si tratta?


Inoltre, volevi fare il contrario


msg_criptato[k] = alfabeto[j+1];


Una stringa la stampi direttamente, non c'è bisogno di un ciclo. Un conto è se stampi carattere per carattere ma tu stampi la stringa.


printf("Il messaggio criptato è: %s", msg_criptato);


Notare che stampavi sempre l'81-esimo elemento del tuo array di char che nel tuo caso sarebbe dovuto essere il terminatore di stringa.

Quello della stringa, pensandoci, sono stato un po' sbadato, pensavo che stampasse una variabile dell'array per volta. Non capisco invece il fatto che stampavo sempre l'81mo elemento. (Tra l'altro non me lo compila nemmeno, quindi non potevo stampare proprio niente)

In effetti il ragazzo mostra carenze nella conoscenza del linguaggio C. Il mio consiglio è magari di farlo in Java, dove alcuni di questi problemi non sussistono. Altrimenti, studiarsi C per bene.

In effetti i pointer non li so usare, ma per ora penso di imparare il C.

---

Comunque ancora ho un errore alla riga 24: prog.c:24: error: expected expression before ‘[’ token.
Ma che cosa manca??

EDIT: Trovato l'errore, c'è una [ di troppo. L'ho compilato ma non va, mi stampa una riga vuota. Come mai?

ndakota
20-11-2011, 18:16
Rimetti codice e cosa ottieni. Così non capisco.

Filly95
20-11-2011, 18:43
Ecco il codice corretto: http://codepad.org/La58gWru.
In pratica mi restituisce una riga vuota come messaggio criptato.

ndakota
20-11-2011, 18:54
Prova ad aggiungere queste due righe prima della stampa del messaggio criptato.


msg_criptato[k] = '\0';
printf("k = %d", k);


Così settiamo il fine stringa e vediamo k a quanto è arrivata per sicurezza. Purtroppo non ho compilatori C installati quindi non riesco ad aiutarti concretamente.

Filly95
20-11-2011, 19:57
Mi dice k = 0. Non è un buon segno, vero?

ndakota
20-11-2011, 21:15
Beh, vuol dire che non entra mai nell'if. Indaga sul perchè. Assicurati che il messaggio sia tutto in maiuscolo vista la natura del tuo alfabeto. Per esempio potresti, subito dopo aver letto da tastiera la stringa del messaggio, trasformarla tutta in maiuscolo con qualcosa del genere


for(int i = 0; i < strlen(msg); i++)
msg[i] = toupper(msg[i]);


Includendo ctype.h. Si potrebbe scrivere anche meglio ma non tocco il C da un po'.

http://www.cplusplus.com/reference/clibrary/cctype/toupper/