Torna indietro   Hardware Upgrade Forum > Software > Programmazione

realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
Hogwarts arriva in fascia media grazie a realme, con una special edition che unisce la Quadra Light-Sensing Color-changing Tech, un baule in stile Hogwarts Express pieno di collezionabili e una scheda tecnica sostanzialmente identica al 16 Pro di partenza: ecco cosa cambia davvero, come si comporta nell'uso quotidiano e quanto vale in base al prezzo di 699,99 euro
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
REDMI Note 17 Pro porta in fascia media una batteria da 8.340 mAh con ricarica HyperCharge a 67W, un display AMOLED da 6,83 pollici capace di picchi di luminosità molto elevati e una struttura certificata TÜV SÜD contro cadute e infiltrazioni d'acqua, il tutto racchiuso in una scocca da 223 grammi. Lo abbiamo provato per diversi giorni tra fotocamera, prestazioni, autonomia e prezzo sul mercato italiano
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra integra un sensore da 1 pollice 8K, ottiche Leica e triplo chip IA. Tra schermo OLED rimovibile, workflow I-Log a 10 bit e stabilizzazione a tre assi, analizziamo le doti tecniche di una gimbal camera pensata per i professionisti
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 10-06-2021, 11:18   #1
sabansa01
Junior Member
 
Iscritto dal: Jun 2021
Messaggi: 5
[C] Problema con cifrario di Cesare

Ciao, sono alle prime armi con la programmazione e sto avendo problemi con un programma che non riesco a far funzionare, mi ci sto sbattendo da giorni...
La traccia consiste nel costruire un programma che si rifa al cifrario di cesare. In particolare si prende in input una stringa del tipo 4<parola-altraparola. Stringa all'interno della quale il primo carattere è detto "chiave", il secondo "direzione", i trattini separano le parole e il punto indica la fine della frase. La "traduzione" avviene, per ogni lettera della parola, prendendo la lettera che si trova *chiave* posti indietro/avanti (dipende dalla direzione) dell'alfabeto. Se ad esempio la lettera da tradurre è z e dobbiamo andare di tre posti avanti, si ricomincerà dalla a e viceversa.
Più semplicemente, se l'input è "3>come-stai." , l'output sarà frph vwdl
Scusate se mi sono spiegato male.

Comunque il mio codice è questo:
Qui trovo la chiave
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100

int caesar_key(char *input)
{
	int in, key;
	in = input[0];
	key = 48 - in;
	
	return key;
}
Qui trovo la direzione
Codice:
int caesar_direction(char *input)
{
	int direction;
	if(input[1] == '<')
	    direction = 0;
	if(input[1] == '>')
	    direction = 1;
	
	return direction;
}
Qui traduco l'input
Codice:
char *caesar_code(int key, int direction, char *input)
{
	char *out;
	int end, i = 2;
	
	do
	{
    	for(; input[i]!='-' && input[i]!='.'; i++)
		{
			if(direction==0)
			{
				if(input[i] >= ('a' + key))
			    	out[i-2] = input[i]-key;
				else
			    	out[i-2] = 'z' - ((key-(input[i]-'a'))-1);
			}
		
			else if(direction==1)
			{
				if(input[i] <= ('z' - key))
			    	out[i-2] = input[i] + key;
				else
			    	out[i-2] = 'a' + ((key-('z'- input[i]))+1);
			}
		
			else
			{
		    	printf("\nERRORE - caesar_direction non riconosciuta\n");
		    	return NULL;
			}
		}
	
		if (input[i] == '-')
		{
			out[i-2] == ' ';
			i++;
			end = 0;
		}
	
		else if(input[i] == '.')
		{
			return out;
	    	end = 1;
	    }
	    
	    else
	    {
	    	printf("\nERRORE - . o - non trovato\n");
	    	return NULL;
		}
	}while(end == 0);
}
E questo è il main
Codice:
int main()
{
	char *input, *output;
	int key, direction;
	input = (char*)malloc(sizeof(char[MAX]));
	output = (char*)malloc(sizeof(char[MAX]));
	
	printf("Scrivere la parola da tradurre: ");
	scanf("%s", input);
		
	key = caesar_key(input);
	direction = caesar_direction(input);
	output = caesar_code(key, direction, input[MAX]);
	
	printf("\nTraduzione:\t%s", output);
		
	return 0;
}
Il problema si pone già al momento dello scanf: premo invio dopo aver scritto l'input, rimane fermo 3 secondi senza scrivere niente, e si chiude il programma.

Ovviamente ho già trovato altri modi per scrivere il programma, però per me è un esercitazione e vorrei capire cosa ho sbagliato, dato che ciò che ho trovato è strutturato in modo totalmente diverso da come ho fatto io.

Grazie per l'attenzione

Ultima modifica di sabansa01 : 10-06-2021 alle 16:03.
sabansa01 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 12:43   #2
Kaya
Senior Member
 
Iscritto dal: Apr 2005
Messaggi: 3302
Ho provato a compilarlo al volo e ottengo:

error: invalid conversion from ‘char’ to ‘char*’ [-fpermissive]
output = caesar_code(key, direction, input[MAX]);
Kaya è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 13:14   #3
sabansa01
Junior Member
 
Iscritto dal: Jun 2021
Messaggi: 5
A me non usciva niente... però ho provato a cambiare quella riga, e semplicemente ho tolto il [MAX]

Codice:
output = caesar_code(key, direction, input);
Adesso almeno il codice supera lo scanf, e se l'input è scritto correttamente(es. 5<ciao-mondo.) traduce bene solo la prima parola, poi non va avanti
sabansa01 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 14:58   #4
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
Nella funzione caesar_code non hai allocato spazio per la variabile out in cui scrivi l'output. Inoltre nel chiamante non è necessario allocare spazio per la variabile output.

Ultima modifica di wingman87 : 10-06-2021 alle 15:25.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 15:44   #5
sabansa01
Junior Member
 
Iscritto dal: Jun 2021
Messaggi: 5
Grazie delle risposte, ho fatto alcune modifiche (premetto col dire che se non alloco la memoria nel main il programma non funziona).

Ora i problemi sono questi:
1) Il codice funziona solo per la prima parola

2) con un input del tipo 3<ciao, alle lettere "c" e "a" dovrebbero corrispondere le lettere "z" e "x", invece al loro posto mi escono altri simboli e punteggiature, come se non prendesse in considerazione il dover "ritornare alla z", che invece ho incluso nel codice.

3) con "<" la direzione dovrebbe essere da destra verso sinistra e con ">" viceversa. Il programma, invece, fa il contrario. Il problema è facilmente risolvibile scambiando i codici negli if in caesar_code, ma comunque non capisco il perchè...

Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100

int caesar_key(char *input)
{
	int in, key;
	in = input[0];
	key = 48 - in;
	
	return key;
}

int caesar_direction(char *input)
{
	int direction;
	if(input[1] == '<')
	    direction = 0;
	else if(input[1] == '>')
	    direction = 1;
	
	return direction;
}

char *caesar_code(int key, int direction, char *input)
{
	char *out;
	out = (char*)malloc(sizeof(char[MAX]));
	int end, i = 2;
	
	do
	{
    	for(; input[i]!='-' && input[i]!='.'; i++)
		{
			if(direction==0)
			{
				if(input[i] >= ('a' + key))
			    	out[i-2] = input[i]-key;
				else
			    	out[i-2] = 'z' - ((key-(input[i]-'a'))-1);
			}
		
			else if(direction==1)
			{
				if(input[i] <= ('z' - key))
			    	out[i-2] = input[i] + key;
				else
			    	out[i-2] = 'a' + ((key-('z'- input[i]))+1);
			}
		
			else
			{
		    	printf("\nERRORE - caesar_direction non riconosciuta\n");
		    	return NULL;
			}
		}
	
		if (input[i] == '-')
		{
			out[i-2] == ' ';
			i++;
			end = 0;
		}
	
		else if(input[i] == '.')
		{
			return out;
	    	end = 1;
	    }
	    
	    else
	    {
	    	printf("\nERRORE - . o - non trovato\n");
	    	return NULL;
		}
	}while(end == 0);
}
	
int main()
{
	char *input, *output;
	int key, direction;
	input = (char*)malloc(sizeof(char[MAX]));
	output = (char*)malloc(sizeof(char[MAX]));
	
	printf("Scrivere la parola da tradurre: ");
	scanf("%s", input);
		
	key = caesar_key(input);
	direction = caesar_direction(input);
	output = caesar_code(key, direction, input);
	
	printf("\nTraduzione:\t%s", output);
		
	return 0;
}
sabansa01 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 15:56   #6
sabansa01
Junior Member
 
Iscritto dal: Jun 2021
Messaggi: 5
Ho risolto gli ultimi due problemi! Avevo sbagliato nella prima funzione, al posto di 48- in andava in-48

Ora rimane solo un problema che non capisco: la seconda parola, se inserita, non viene tradotta.

Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100

int caesar_key(char *input)
{
	int in, key;
	in = input[0];
	key = in - 48;
	
	return key;
}

int caesar_direction(char *input)
{
	int direction;
	if(input[1] == '<')
	    direction = 0;
	else if(input[1] == '>')
	    direction = 1;
	
	return direction;
}

char *caesar_code(int key, int direction, char *input)
{
	char *out;
	out = (char*)malloc(sizeof(char[MAX]));
	int end, i = 2;
	
	do
	{
    	for(; input[i]!='-' && input[i]!='.'; i++)
		{
			if(direction==0)
			{
				if(input[i] >= ('a' + key))
			    	out[i-2] = input[i]-key;
				else
			    	out[i-2] = 'z' - ((key-(input[i]-'a'))-1);
			}
		
			else if(direction==1)
			{
				if(input[i] <= ('z' - key))
			    	out[i-2] = input[i] + key;
				else
			    	out[i-2] = 'a' + ((key-('z'- input[i]))+1);
			}
		
			else
			{
		    	printf("\nERRORE - caesar_direction non riconosciuta\n");
		    	return NULL;
			}
		}
	
		if (input[i] == '-')
		{
			out[i-2] == ' ';
			i++;
			end = 0;
		}
	
		else if(input[i] == '.')
		{
			return out;
	    	end = 1;
	    }
	    
	    else
	    {
	    	printf("\nERRORE - . o - non trovato\n");
	    	return NULL;
		}
	}while(end == 0);
}
	
int main()
{
	char *input, *output;
	int key, direction;
	input = (char*)malloc(sizeof(char[MAX]));
	output = (char*)malloc(sizeof(char[MAX]));
	
	printf("Scrivere la parola da tradurre: ");
	scanf("%s", input);
		
	key = caesar_key(input);
	direction = caesar_direction(input);
	output = caesar_code(key, direction, input);
	
	printf("\nChiave: %d", key);
	printf("\nDirezione: %d ", direction);
	if(direction == 0)
	    printf("(dx-sx)");
	else if(direction == 1)
	    printf("(sx-dx)");
	printf("\nTraduzione: %s", output);
		
	return 0;
}

Ultima modifica di sabansa01 : 10-06-2021 alle 16:03.
sabansa01 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 16:18   #7
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
Il problema è in questo if:
Codice:
		if (input[i] == '-')
		{
			out[i-2] == ' ';
			i++;
			end = 0;
		}
La riga in rosso ha un = di troppo, così non avviene l'assegnazione.
La ragione per cui non vedi la seconda parola è che probabilmente out è inizializzato tutto a zero e lo zero è il terminatore di stringa.
Da quello che ricordo però malloc non dovrebbe inizializzare tutto a zero (per quello c'è calloc). Forse è una caratteristica del compilatore, non saprei...

Volevo aggiungere che se consideri il fatto che malloc in teoria non inizializza il vettore a zero, nel caso in cui input[i] == '.' dovresti anche scrivere in out[i-2] il valore zero, altrimenti out conterrà una stringa priva di terminatore.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 16:25   #8
sabansa01
Junior Member
 
Iscritto dal: Jun 2021
Messaggi: 5
Grazie mille... Un errore di distrazione che non avevo notato, ora il programma funziona benissimo. Fra l'altro, come avevi detto, senza out[i-2]=0 la frase terminava con un simbolo, invece aggiungendolo la stringa si conclude come dovrebbe. Grazie ancora!

Il codice finale

Codice:
/************ CIFRARIO DI CESARE - INPUT DEL TIPO *key**direction(< o >)**parola1*-*parola2*. ************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100

int caesar_key(char *input)
{
	int in, key;
	in = input[0];
	key = in - 48;
	
	return key;
}

int caesar_direction(char *input)
{
	int direction;
	if(input[1] == '<')
	    direction = 0;
	else if(input[1] == '>')
	    direction = 1;
	
	return direction;
}

char *caesar_code(int key, int direction, char *input)
{
	char *out;
	out = (char*)malloc(sizeof(char[MAX]));
	int end, i = 2;
	
	do
	{
    	for(; input[i]!='-' && input[i]!='.'; i++)
		{
			if(direction==0)
			{
				if(input[i] >= ('a' + key))
			    	out[i-2] = input[i]-key;
				else
			    	out[i-2] = 'z' - ((key-(input[i]-'a'))-1);
			}
		
			else if(direction==1)
			{
				if(input[i] <= ('z' - key))
			    	out[i-2] = input[i] + key;
				else
			    	out[i-2] = 'a' + ((key-('z'- input[i]))-1);
			}
		
			else
			{
		    	printf("\nERRORE - caesar_direction non riconosciuta\n");
		    	return NULL;
			}
		}
	
		if (input[i] == '-')
		{
			out[i-2] = ' ';
			i++;
			end = 0;
		}
	
		else if(input[i] == '.')
		{
			out[i-2] = 0;
			return out;
	    }
	    
	}while(end == 0);
}
	
int main()
{
	char *input, *output;
	int key, direction;
	input = (char*)malloc(sizeof(char[MAX]));
	output = (char*)malloc(sizeof(char[MAX]));
	
	printf("Scrivere la parola da tradurre: ");
	scanf("%s", input);
		
	key = caesar_key(input);
	direction = caesar_direction(input);
	output = caesar_code(key, direction, input);
	
	printf("\nChiave: %d", key);
	printf("\nDirezione: %d ", direction);
	if(direction == 0)
	    printf("(dx-sx)");
	else if(direction == 1)
	    printf("(sx-dx)");
	printf("\nTraduzione: %s", output);
		
	return 0;
}

Ultima modifica di sabansa01 : 10-06-2021 alle 16:30.
sabansa01 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 16:47   #9
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
Bene, però scusa se insisto ma nel main non devi allocare spazio per la variabile output, puoi rimuovere questa riga:
Codice:
output = (char*)malloc(sizeof(char[MAX]));
Insisto perché è un memory leak ed è bene notarli anche se in questo caso è irrilevante perché il programma termina subito. Se questo codice fosse parte di un progetto più grande e venisse eseguito tante volte sarebbe tutto spazio sprecato e mai deallocato.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 10-06-2021, 16:51   #10
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
mi hai battuto sul tempo, ci stavo lavorando su anch'io
misterx è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole! realme 16 Pro Harry Potter Edition: il nuovo mid...
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce Recensione REDMI Note 17 Pro: il midrange con ba...
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema Insta360 Luna Ultra: la potenza del sensore da 1...
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
28 offerte Amazon da non perdere: e-bike...
'Il rapporto con Sony è rimasto f...
Vision AI Upscaling e Micro RGB AI Engin...
NVIDIA GeForce RTX 6000, anche il leaker...
In arrivo la 'pagella' per i datacenter:...
Celle perovskite-silicio al 34% grazie a...
Apple prepara il suo nuovo hub intellige...
La Cadillac Lyriq-V elettrica sbarca in ...
Amazon: arriva l'opzione per aggiungere ...
Un developer usa Claude Code per creare ...
Relativity Space annuncia i progressi ne...
Il nuovo Resident Evil supera ogni prece...
Hai appena sconfitto un boss e parte lo ...
Ray tracing anche senza montagne di VRAM...
TSMC prepara il processo a 1,4 nm: quatt...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 06:55.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v