PROBLEMA Ritorno di un elemento della lista da linea di comando

davidson

Nuovo Utente
33
5
ho avuto un problema con un programma e non so cosa fare arrivati a questo punto

dato un file txt dove all'interno abbiamo un numero qualsiasi per riga , copi l'intero contenuto in una lista
e da riga di comando ./nomeprogramma numeri.txt 4 mi deve ritornare il quarto elemento arrotondato con la funzione Round della libreria Math
file
2
3
45
1.5

ecco il codice spero che mi possate aiutare in qualche modo grazie



Codice:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<math.h>



struct listinfo
{
   double elem;
   int pos;
   struct listinfo *prox;
 
};
typedef struct listinfo lista;

//Prototipi di funzione//
lista* inizializza(lista *pointer);
//lista* inserisci(lista *pointer,int elemento);
lista* inseriscicoda(lista *pointer,double elemento);
lista* carica(lista *pointer,char *nomefile);
lista* ordina(lista *pointer);
lista* RitornaPosizione(lista*pointer,int argv2);
//void stampa(lista *pointer);
//double stampaelemento(lista *pointer,int argv2);


int main(int argc ,char *argv[])

{
int i;
double ris;
//puntatore a lista
lista *lista1;
int argv2;
char*nomefile = argv[1];
//converto il valore da tastiera stringa in intero
argv2 = atoi(argv[2]);

//inizializza la lista vuota//

lista1 = inizializza(lista1);
lista1 = carica(lista1,nomefile);
lista1=ordina(lista1);
lista1 = RitornaPosizione(lista1,argv2);
ris=lista1->elem;
printf("l'elemento desiderato e' %lf\n",ris);
return round(ris);
}
/*
for(i=1;i<argc;i++)
{
     while(lista1!=NULL)
   {
     if(argv==lista->elem)

     {

       return round(i);
     }

   else

   {
     lista1=lista1->prox;

     return round(i);


   }

   }


}
*/

/*void stampalista(lista *pointer,int val)
{
while(pointer!=NULL)
{
   printf("%lf   ",pointer->elem);

   pointer=pointer->prox;
}

}
*/

/*double stampaelemento(lista*pointer,int argv2)
{
   double risultato;

 
     if(pointer->pos == argv2)
     {
        printf("%lf ",pointer->elem);

      risultato=pointer->elem;

      return risultato;
     }

   


     else
      {
       pointer=pointer->prox;

      }
 
}

*/



lista* inizializza(lista*pointer)
{
   pointer = NULL;
   return NULL;
}


// inserimento in testa

/*lista* inserisci(lista *pointer,int elemento)
{lista *testa = NULL;
pointer=(lista*)malloc(sizeof(lista));
pointer->elem=elemento;
pointer->prox=testa;
testa = pointer;
 
return pointer;}
*/

lista* inseriscicoda(lista *pointer,double elemento)
{
lista *punt,*cursore,*cursore1;
cursore=pointer;

punt=(lista*)malloc(sizeof(lista));   //dato da inserire
punt->elem=elemento;
punt->prox=NULL;

if (pointer==NULL) {pointer=punt;}   //se la lista è vuota lo metto in testa
else{

while(cursore!=NULL)         //scansione fino alla fine
{cursore1=cursore;           //cursore1 serve per avere l'ultima posizione di cursore
  cursore=cursore->prox;}
  cursore1->prox=punt;}
return pointer;}




lista* carica(lista* pointer,char*nomefile)
{
double a,b;
FILE *fp;
if((fp=fopen(nomefile,"r"))==NULL)
return pointer;
pointer=NULL;
while (b=(fscanf(fp,"%lf",&a))!=EOF)
{
pointer=inseriscicoda(pointer,a);
}

fclose(fp);
return pointer;
}





lista* ordina(lista *pointer)
{
   if (pointer && pointer->prox) {
     int k;

     do {
                        lista *punt = pointer;

       k = 0;
       while (punt->prox) {
         lista *punt1 = punt;

         punt = punt->prox;
         if ((punt1->elem) > (punt->elem)) {
           int tmp = punt1->elem;

           punt1->elem = punt->elem;
           punt->elem = tmp;
           k = 1;
         }
       }
     } while (k != 0);
   }

   return pointer;
}


/*lista* ricerca(lista * pointer,int element)
{
   while(pointer!=NULL)
   {
     if(element == pointer->elem)
     {
       return pointer;
     }

     else

     {

       pointer= pointer->prox;

     }


   }

}

*/

lista* RitornaPosizione(lista*pointer,int argv2)

{     //contatore che aggiorna la posizione del nodo//
   int posizione=0;

   lista*p1 = pointer;

 
 
   while(p1 != NULL)
   {
     posizione++;
  
     p1->pos=posizione;

     if(p1->pos == argv2)
     {
       return p1;
    
     }


     p1=p1->prox;
    
   }


}
 
Ultima modifica:

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,853
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Non hai specificato che tipo di problema hai però.
Sicuramente, già ad un primo sguardo, ho notato due cose:

1) se inizializzi il contatore del ciclo a 1 e scorri sino a che è < N, ti perderai un valore (se N=10, i =1 ed ha condizione i<N, guardi solo 9 elementi).
2) lo scopo è restituire il round del 4 elemento della lista, quindi devi accedere alla lista ed in particolare al campo double facendo il round di questo valore, non della posizione/indice i.
 

davidson

Nuovo Utente
33
5
Non hai specificato che tipo di problema hai però.
Sicuramente, già ad un primo sguardo, ho notato due cose:

1) se inizializzi il contatore del ciclo a 1 e scorri sino a che è < N, ti perderai un valore (se N=10, i =1 ed ha condizione i<N, guardi solo 9 elementi).
2) lo scopo è restituire il round del 4 elemento della lista, quindi devi accedere alla lista ed in particolare al campo double facendo il round di questo valore, non della posizione/indice i.

attenzione alcuni parti l'ho commentate non devi considerarle , precedute da */ e terminano con */
while(p1 != NULL)
{
posizione++;

p1->pos=posizione;

if(p1->pos == argv2)
{
return p1;

}


p1=p1->prox;
io ho pensato di aggiungere un campo pos come membro della lista che sarebbe la posizione e il valore viene inserito e incrementato per ogni elemento della lista con
posizione++
all'inizio vale 0 , finche p1 punta ad un nodo allora incremento posizione e posizione al primo ciclo iterativo assume il valore 1, p1 accede al primo nodo
nello specifico nella variabile pos che è vuota e la riempio con posizione in modo tale che valga 1 poi confronto il valore di argv2 convertito in int con il valore pos,
se il valore pos concide con argv2 esempio: ./programma 2 ritorna il puntatore del secondo nodo della lista altrimenti vado al nodo successivo. Ho un dubbio nel momento che entro nell'if e faccio il return del puntatore , è terminato il ciclo giusto?

Nel main il puntatore lista1 sarà quel puntatore del nodo che ha la componente pos == argv2, quindi ho pensato mi creo un variabile double e gli passo il membro della lista1 cioè ris = lista1->elem dopodichè stampo il valore e ritorno il valore arrotondato

Mi piacerebbe sapere dove ho sbagliato, il problema è che non so dove ho sbagliato , il problema c'è ma non lo trovo mi sono spiegato male
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,853
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Ho dovuto rileggere più volte quanto hai scritto, ma forse ho capito...

La richiesta iniziale è in realtà quella di restituire il valore arrotondato, e non l'elemento della lista (ma supponiamo anche sia corretto invece restituire l'elemento, purchè il valore sia arrotondato).
Ciò che devi fare è semplicemente scorrere la lista tenendo traccia del numero di elementi e restituire l'elemento della lista (o il suo valore). Non capisco perchè assegnare la posizione all'elemento della lista quando vai a leggerla... a che ti serve? A te serve sapere se posizione == argv2.
Se invece l'elemento pos è già stato settato in precedenza (magari in fase di caricamento dei dati) allora è anche errato settarlo a questo punto, in quanto lo sovrascriveresti. Quindi se il caso fosse quest'ultimo dovresti verificare che lista->pos == argv2, ma senza assegnare prima un valore.

Si, il return restituisce il controllo al chiamante (interrompendo il ciclo) e restituendo un puntatore di tipo lista.

Puoi anche iniziare direttamente da posizione=1:
C:
lista* RitornaPosizione(lista*pointer,int argv2)
{     //contatore che aggiorna la posizione del nodo//
   int posizione=1;
   lista*p1 = pointer;

   while(p1 != NULL)
   {
 
     p1->pos=posizione;

     if(p1->pos == argv2)
     {
       return p1;
   
     }
     posizione++;

     p1=p1->prox;
   
   }

}
Fai attenzione poichè se p1->prox è NULL, allora il ciclo terminerà, ma servirà restituire un valore opportuno (ad esempio return NULL) ad indicare che il valore non è presente.

Questa cosa inoltre non ha molto senso:

C:
ris=lista1->elem;
printf("l'elemento desiderato e' %lf\n",ris);
return round(ris);

Il round va nel printf (e se lo vuoi formattato come intero dovresti usare %d). Inoltre quel return è relativo al main() (e indica al sistema operativo l'esito della terminazione del programma).

Se fai modifiche al codice, postalo così come lo stai utilizzando, almeno si può capire che problema si verifica, evitando anche di commentare parti che permettono un corretto funzionamento (ora ho solamente letto il codice, ed ho notato queste cose).
 

davidson

Nuovo Utente
33
5
ho quasi risolto nel senso che devo verificare il valore di ritorno della lista con echo $? e mi ritorna 0 invece mi deve ritornare l'elemento della lista desiderato
//fine main//
printf("l'elemento da ritornare e' %lf",lista->elem);
return round(lista->elem);
//fine main//
devo fare il test che il prof mi ha chiesto con echo $? su linux ma ritorna 0 mentre deve ritornare il quinto elemento che sarebbe 8.
esempio ho la lista disposta in questo modo
0
2
4
6
8
scrivo su linea di comando ./lista numeri.txt 5
e mi stampa la lista ordinata
0,2,4,6,8
il valore da ritornare e' 8
dopo che il programma ha terminato l'esecuzione devo verificare il valore di ritorno in questo modo echo $?
risultato 0 com'è possibile?
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!