Esercizio in c89 sulla successione di Fibonacci

Gius1805

Nuovo Utente
12
0
Buonasera,
qualcuno potrebbe dare un occhiata a questo programma per controllare che sia giusto? Grazie in anticipo.

Si ricordi che la successione di Fibonacci è costituita da una sequenza di numeri interi in cui i primi due elementi sono per definizione 0 e 1, e ciascun numero successivo è ottenuto come somma dei due precedenti. La sequenza è quindi: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … Realizzare un programma che riceve come argomento da riga di comando il nome di un file di testo contenente una sequenza di lunghezza indefinita di numeri interi. Il programma apre il file e verifica se la sequenza di numeri contenuta sia la successione di Fibonacci (partendo da 0) o meno. In caso affermativo il programma stampa a video 1 altrimenti 0. Controllare e segnalare eventuali situazioni di errore.
C:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    FILE* fp;
    int *p, n=1, N=1, flag=1, i;

    if(argc==2){
        fp=fopen(argv[i], "rb");
        if(fp){
            while(n==N){ /* continuo finchè non sono sicuro di aver letto tutto*/
                p=malloc(sizeof(int)*N); /*alloco matrice dinamica di N elementi*/
                if(p){
                    n=fread(p, sizeof(int), N, fp); /*leggo N elementi*/
                    if(n==N){ /* potrebbero esserci elementi non letti*/
                        free(p);
                        N++;
                    }
                }
            }
            for(i=0; i<N-2 && flag==1; i++){
            if((p+i)+(p+i+1)==(p+i+2))
                flag=0;
            else
                flag=1;
            }
            free(p);
            printf("%d", flag);
            return 0;
        }
    }
}
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,222
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
Ciao, ci sono alcuni errori.
  • la variabile i non è inizializzata, ed è un errore grave (inoltre non ti serve dato che hai solo 1 file, quindi toglila e usa 1 come indice)
  • la malloc non devi farla dentro al ciclo, spostala sopra
  • il contatore del while non è esattamente corretto
  • il for che scorre gli elementi: tu stai incrementando l'indirizzo del puntatore, non lo stai dereferenziando
  • cosa meno grave, ma comunque secondo me da correggere: il maiuscolo viene utilizzato per indicare delle costanti (è una convenzione)
Per renderlo più leggibile puoi anche mettere un "return" dopo aver verificato fp (così non scrivi tutto dentro a quell'if; devi solo invertire la condizione).

Come sono disposti gli elementi nel file? Uno per riga?
 

Gius1805

Nuovo Utente
12
0
Ciao, ci sono alcuni errori.
  • la variabile i non è inizializzata, ed è un errore grave (inoltre non ti serve dato che hai solo 1 file, quindi toglila e usa 1 come indice)
  • la malloc non devi farla dentro al ciclo, spostala sopra
  • il contatore del while non è esattamente corretto
  • il for che scorre gli elementi: tu stai incrementando l'indirizzo del puntatore, non lo stai dereferenziando
  • cosa meno grave, ma comunque secondo me da correggere: il maiuscolo viene utilizzato per indicare delle costanti (è una convenzione)
Per renderlo più leggibile puoi anche mettere un "return" dopo aver verificato fp (così non scrivi tutto dentro a quell'if; devi solo invertire la condizione).

Come sono disposti gli elementi nel file? Uno per riga?
  • Il primo errore è un errore di distrazione, so che dovevo scrivere 1 invece che i. Il che lo rende ancora più grave?.
  • La malloc l'ho inserita dentro il ciclo while perché modificando ogni volta la dimensione devo ogni volta allocare una nuova matrice.
  • Non capisco perché il while non è esattamente corretto
  • Per quanto riguarda la disposizione degli elementi del file non posso aggiungere altro perché tutto quello che so è nella descrizione dell'esercizio.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,222
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 capisco perchè dici che modifichi ogni volta la dimensione della matrice... oltretutto tu non hai una matrice, ma hai un vettore di N elementi. Tu hai una sola sequenza di fibonacci, a quanto dice la traccia.

Dico che non è esattamente corretto perchè di solito leggi sino a che non raggiungi "end of file".

Inoltre, come fai a leggere se non sai come sono disposti gli elementi?
 

Gius1805

Nuovo Utente
12
0
Non capisco perchè dici che modifichi ogni volta la dimensione della matrice... oltretutto tu non hai una matrice, ma hai un vettore di N elementi. Tu hai una sola sequenza di fibonacci, a quanto dice la traccia.

Dico che non è esattamente corretto perchè di solito leggi sino a che non raggiungi "end of file".

Inoltre, come fai a leggere se non sai come sono disposti gli elementi?
Io devo salvare i valori contenuti nel file in un array ma non so quanto deve essere lungo. La mia idea era di allocare una matrice e se il numero di elementi letti fosse stato uguale alla dimensione deallocarla e aumentare N (mi ricordo che è sbagliata la maiuscola) in modo che alla prossima allocazione di memoria avrò un vettore più grande. Continuo così finché il numero di elementi del file binario è minore della dimensione del vettore, quando questo accadrà saprò di aver letto tutto e di aver salvato i valori in un array abbastanza grande.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,222
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
Ma tu non stai allocando una matrice. Tu allochi sempre nuova memoria.

Hai diverse strade qui. Puoi leggere tutto il file per contare gli elementi, o puoi non doverli nemmeno memorizzare... puoi fare il check subito.
Un'altra soluzione è allocare già abbastanza memoria, e riallocare quando non è più sufficiente. Ma ha senso se devi mantenere l'array per riutilizzarlo dopo.

La cosa migliore e più semplice è che leggi 2 valori, li sommi e vedi se sono uguali al terzo valore.

C:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    if(argc != 2) {
        printf("Usage: file.exe <nome_file.txt>");
        return -1;
    }
    
    int n1, n2, n3;
    FILE *fp = fopen(argv[1], "rb");
    
    fscanf(fp, "%d", &n1);
    fscanf(fp, "%d", &n2);
    
    int bytes_read = 0;
    for(;;) {
        bytes_read = fscanf(fp, "%d", &n3);
        
        if(bytes_read == EOF || (n1+n2) != n3)
            break;
        
        n1 = n2;
        n2 = n3;
    }
    
    printf("Valida? %d", (bytes_read == EOF));
    
    return 0;
}

Il file può essere formattato così:
Codice:
0 1 1 2 3 5 8

oppure così:

Codice:
0
1
1
2
3
5
8

L'ho un pò "buttato li".
 

Gius1805

Nuovo Utente
12
0
Ma tu non stai allocando una matrice. Tu allochi sempre nuova memoria.

Hai diverse strade qui. Puoi leggere tutto il file per contare gli elementi, o puoi non doverli nemmeno memorizzare... puoi fare il check subito.
Un'altra soluzione è allocare già abbastanza memoria, e riallocare quando non è più sufficiente. Ma ha senso se devi mantenere l'array per riutilizzarlo dopo.

La cosa migliore e più semplice è che leggi 2 valori, li sommi e vedi se sono uguali al terzo valore.

C:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    if(argc != 2) {
        printf("Usage: file.exe <nome_file.txt>");
        return -1;
    }
   
    int n1, n2, n3;
    FILE *fp = fopen(argv[1], "rb");
   
    fscanf(fp, "%d", &n1);
    fscanf(fp, "%d", &n2);
   
    int bytes_read = 0;
    for(;;) {
        bytes_read = fscanf(fp, "%d", &n3);
       
        if(bytes_read == EOF || (n1+n2) != n3)
            break;
       
        n1 = n2;
        n2 = n3;
    }
   
    printf("Valida? %d", (bytes_read == EOF));
   
    return 0;
}

Il file può essere formattato così:
Codice:
0 1 1 2 3 5 8

oppure così:

Codice:
0
1
1
2
3
5
8

L'ho un pò "buttato li".
Ho capito. Grazie per l'aiuto e soprattutto per la pazienza?
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili