I dati sono stati passati correttamente anche perchè ho fatto un semplice ctrl+c e ctrl+v, il problema del compilatore scolastico è che non mi fa vedere l'output che esce a lui e mi riporta solamente l'errore che avevo scritto, l'unico caso in cui posso avere l'errore è nel caso in cui inserisco il valore "2147483648" direttamente(Quindi dovrebbe riportarmi l'overflow dopo il tentativo di concatenamento) perchè non è presente negli altri testcase. Comunque ho provato a rimuovere le 2 variabili globali e mi da lo stesso errore. Grazie per il consiglio sulla lista. Questo è il codice che ho riscritto:@Gead1 (great nickname BTW)
Ieri ho avuto tempo di provare il tuo programma, che funziona bene anche a me. Sei sicuro che lo hai trasferito correttamente nel computer scolastico? Sei sicuro di avere immesso i dati correttamente? Quando ti dà errore, al primo passo, in alcuni o in tutti?
Il tuo codice mi pare ben strutturato, se posso dare un consiglio è di implementare la lista di tipo LIFO in quanto è proprio quella che si usa per la notazione polacca inversa (dove il primo operando che si usa è l’ultimo a essere immesso), ti semplifica il codice non poco.
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LENGHT 35
//Struttura che conterrà i valori delle espressioni
typedef struct n{
int numero;
struct n *nextPtr;
}Numeri;
typedef Numeri *numPtr;
//Dichiarazione funzioni
int acquisisci(char *stringa);
void azzera(numPtr *nPtr);
unsigned short int concatena(numPtr *nPtr, short int val);
void newNum(numPtr *nPtr, short int val);
unsigned short int calcolo(numPtr *nPtr, short int temp);
void stampa(numPtr *nPtr, unsigned short int ov);
void complemento2(int num);
//Inizio main
int main()
{
short int temp = 0;
unsigned short int ov;
unsigned short int conc;
unsigned short int negativo = 0;
char espressione[LENGHT]; //Variabile che conterrà l'espressione
Numeri *nPtr = NULL; //Dichiarazione e inizializzazione puntatore
while(acquisisci(espressione)){//Ripeto fin quando non trovo il valore "fine"
//Azzero la lista ad ogni reiterazione del ciclo while
azzera(&nPtr);
conc = 0;
ov = 0;
//Analizzo ogni elemento dell'espressione
for(size_t i = 0; i<strlen(espressione); i++){
//Trasformo in int l'iesimo elemento dell'espressione
temp = (int)espressione[i];
//Se abbiamo un "-" seguito da un valore allora abbiamo un numero negativo
if(temp == 45 && isdigit(espressione[i+1])){
negativo = 1;
}
//Se abbiamo un valore intero
else if(temp < 58 && temp > 47){
temp = temp - '0'; //Convertiamo il valore dal suo codice ascii al suo reale valore
if(conc == 1){//Concateniamo al numero letto in precedenza
ov = concatena(&nPtr, temp);
if(ov == 1){
break;
}
}else{ //Oppure creiamo un nuovo elemento in lista
if(negativo == 1){
temp *= -1;
negativo = 0;
}
newNum(&nPtr, temp);
conc = 1;
}
}
//Se il valore è un'operazione (+, - o *) chiamiamo la funzione calcolo
else if(temp == 45 || temp == 43 || temp == 42){
ov = calcolo(&nPtr, temp);
if(ov == 1){
break;
}
}else{//Altrimenti sarà uno spazio e quindi azzariamo conc
conc = 0;
}
}
//Stampiamo il risultato dopo aver analizzato l'espressione
stampa(&nPtr, ov);
}
//Azzeriamo definitivamente la lista
azzera(&nPtr);
}
//Funzione per l'acquisizione della stringa da stdin
int acquisisci(char *stringa){
fgets(stringa, LENGHT, stdin);
stringa[strlen(stringa) - 1] = 0;
if(strcmp(stringa, "fine")){//Se la stringa è "fine" allora restituiamo 1 per interrompere l'esecuzione
return 1;
}else{
return 0;
}
while(getchar() != '\n');
}
//Funzione per azzerare la lista prima di una nuova conversione o alla fine del programma
void azzera(numPtr *nPtr){
//Inizializziamo i puntatori necessari
numPtr corrPtr = *nPtr;
numPtr tempPtr = NULL;
//Libero la memoria allocata per ogni puntatore fino all'ultimo
while(corrPtr != NULL){
tempPtr = corrPtr;
corrPtr = corrPtr->nextPtr;
free(tempPtr);
}
*nPtr = NULL;
}
//Funzione per inzializzare e inserire un nuovo elemento in lista
void newNum(numPtr *nPtr, short int val){
//Inizializziamo i puntatori necessari
numPtr corrPtr = *nPtr;
numPtr precPtr = NULL;
//Allochianmo la memoria per il nuovo nodo e il nuovo nodo
numPtr nuovoPtr = malloc(sizeof(Numeri));
if(nuovoPtr == NULL){
puts("Memoria insufficiente!");
exit(0);
}
nuovoPtr->numero = val;
nuovoPtr->nextPtr = NULL;
//Portiamoci all'ultimo elemento della lista
while(corrPtr != NULL){
precPtr = corrPtr;
corrPtr = corrPtr->nextPtr;
}
//Se la lista è vuota la inizializziamo
if(precPtr == NULL){
nuovoPtr->nextPtr = *nPtr;
*nPtr = nuovoPtr;
}else{ //Altrimenti lo aggiungiamo in
precPtr->nextPtr = nuovoPtr;
nuovoPtr->nextPtr = corrPtr;
}
//Aggiunto un nuovo nodo, avvertiamo che i successivi valori saranno da concatenare
return;
}
//Funzione per la concatenazione
unsigned short int concatena(numPtr *nPtr, short int val){
//Inizializziamo i puntatori e le variabili necessarie
numPtr corrPtr = *nPtr;
numPtr precPtr = NULL;
int temp = 0;
unsigned short int ov = 0;
//Arrivo all'ultimo elemento in lista
while(corrPtr != NULL){
precPtr = corrPtr;
corrPtr = corrPtr->nextPtr;
}
//Concateno il numero e controllo se faccia overflow il concatenamento
if(precPtr->numero<0){
temp = precPtr->numero;
if(temp == -214748364 && val == 9){
ov = 1;
}else{
precPtr->numero = (precPtr->numero * 10) - val;
}
if(temp<precPtr->numero){
ov = 1;
}
}else{
temp = precPtr->numero;
if(temp == 214748364 && val>7){
ov = 1;
}else{
precPtr->numero = (precPtr->numero * 10) + val;
if(temp>precPtr->numero){
ov = 1;
}
}
}
return ov;
}
//Funzione per il calcolo che svolge l'operazione con gli ultimi 2 numeri in lista
unsigned short int calcolo(numPtr *nPtr, short int temp){
numPtr corrPtr = *nPtr;
numPtr precPtr = NULL;
unsigned short int ov = 0;
while(corrPtr->nextPtr != NULL){
precPtr = corrPtr;
corrPtr = corrPtr->nextPtr;
}
int primo = precPtr->numero;
int secondo = corrPtr->numero;
//Controllo overflow moltiplicazione
if(temp == 42){
if(primo == 0 || secondo == 0){//Se abbiamo uno "0" allora la moltiplicazione farà 0
precPtr->numero = 0;
}
if(primo>0){
if(secondo>0){
if(primo > (precPtr->numero = primo*secondo) ){//Se i 2 numeri sono > 0 e temp < primo allora abbiamo overflow
ov = 1;
}
}else{//Primo > 0 e secondo < 0
if(primo < (precPtr->numero = primo*secondo)){//Se primo è minore della molt. allora abbiamo overflow
ov = 1;
}
}
}else{
if(secondo > 0){ //Primo min 0 e sec magg 0
if(primo < (precPtr->numero = primo*secondo)){//Se primo < operazione allora abbiamo overflow
ov = 1;
}
}else{//Anche secondo minore di 0
if(primo > (precPtr->numero = primo*secondo) ){//Se primo > operazione allora overflow
ov = 1;
}
}
}
}
//Controllo overflow somma
else if(temp == 43){
//Se l'operazione è una somma e uno dei due valori è 0 allora restituiamo l'altro valore
if(primo == 0){
precPtr->numero = secondo;
}else if(secondo == 0){
precPtr->numero = primo;
}
if(primo>0){
if(secondo>0){//Primo e secondo > 0
if(primo > (precPtr->numero = primo + secondo)){//Se primo > somma allora overflow
ov = 1;
}
}
}else{
if(secondo > 0){//Eseguiamo l'operazione perchè non può esserci overflow
precPtr->numero = primo + secondo;
}else{
if(primo < (precPtr->numero = primo + secondo)){//Se sec < 0 e primo < somma allora overflow
ov = 1;
}
}
}
}
//Controllo overflow sottrazione
else if(temp == 45){
//Nella sottrazione, se il secondo valore è 0 possiamo ritornare direttamente il primo
if(secondo == 0){
precPtr->numero = primo;
}
if(primo >= 0){
if(secondo>0){//Primo e secondo > 0 eseguiamo sottrazione
precPtr->numero = primo - secondo;
}else{//Secondo minore 0 controlliamo overflow
if(primo >= (precPtr->numero = primo - secondo)){
ov = 1;
}
}
}else{
if(secondo >= 0){//Primo >= 0, secondo < 0 controlliamo overflow
if(primo < (precPtr->numero = primo - secondo)){
ov = 1;
}
}else{//Secondo < 0 eseguiamo sottrazione perchè non può essere overflow
precPtr->numero = primo - secondo;
}
}
}
free(corrPtr);//Liberiamo in nodo che non ci serve più
precPtr->nextPtr = NULL;
return ov;
}
//Funzione per la stampa del valore finale e conversione in c2
void stampa(numPtr *nPtr, unsigned short int ov){
//Se abbiamo un overflow stampiamo l'errore
if(ov == 1){
puts("Overflow!");
ov = 0;
return;
}
numPtr corrPtr = *nPtr;
//Stampiamo il valore e chiamiamo la funzione per il complemento a 2
printf("%d in C2: ", corrPtr->numero);
complemento2(corrPtr->numero);
}
//Funzione per effettuare il complemento a 2
void complemento2(int num){
unsigned short int numconv[32];
unsigned short int cont=31;
unsigned short int spazi=0;
size_t neg=0;
size_t riporto=0;
if(num==1){
printf("0000 0000 0000 0000 0000 0000 0000 0001");
return;
}
if(num==0){
printf("0000 0000 0000 0000 0000 0000 0000 0000");
return;
}
if(num<0){
neg=1;
num *= -1;
}
for(int i=0; i<=cont; i++){
numconv[i]=0;
}
while(num>0){
numconv[cont]=num%2;
cont--;
num=num/2;
}
if(neg==1){
for(int i=0; i<32; i++){
if(numconv[i]==0){
numconv[i]=1;
}
else if(numconv[i]==1){
numconv[i]=0;
}
}
for(int k=31; k>=0; k--){
if(k==31){
numconv[k] += 1;
if(numconv[k]==2){
riporto=1;
numconv[k]=0;
}
}else{
if(riporto==1 && numconv[k]==0){
numconv[k]=1;
riporto=0;
}else if(riporto==1 && numconv[k]==1){
numconv[k]=0;
riporto=1;
}
}
}
numconv[0]=1;
}
for(size_t i=0; i<32; i++){
printf("%d", numconv[i]);
spazi++;
if(spazi==4){
printf(" ");
spazi=0;
}
}
printf("\n");
}
Post unito automaticamente:
Purtroppo non ho la possibilità di operare sulla macchina dove da l'errore perchè è una sorta di compilatore online fornito dall'università e restituisce solo la correttezza dell'output o l'errore come nel mio caso.Non ho il tempo di trovare il problema preciso, compilato stesso test case qui
non da problemi. Per trovare il problema facilmente sulla macchina dove lo da,
Codice:gcc -ggdb -o binario main.c gdb ./binario run