Funzione di funzione in C

Stefanokj

Utente Attivo
333
7
OS
Arch
Ciao ragazzi, ho un probema con le funzioni.
Praticamente ho una struttura che devo riempire, ho fatto una "mega procedura" che mi permette di inserire i valori all'interno della struttura, e fin qui nessun problema, ora devo affinare il codice, devo mettere delle regole per l'inserimento, per esempio una dimensione massima della stringa da inserire (in sostanza controlli sull'input).
Per evitare di fare tutto all'interno della funzione dichiarata prima facendola diventare disordinata, volevo creare delle funzioncine esterne di appoggio.
vi faccio un esempio con il codice così potete capire:

C:
typedef struct{
char nome[DIM1];                 //DIM1 = 10

char indirizzo[DIM2];            //DIM2 = 100
               
}pippo;

void riempiStruttura(pippo *p){                     //sul main avrò definito la variabile di tipo struttura:  pippo p;
          printf("Inserisci nome");
          inserisci(DIM1, pippo->nome);

        

          printf("Inserisci indirizzo");
          inserisci(DIM2, pippo->indirizzo);
}

void inserisci(int dim, char*){
int c=0;
do {
scanf("%64[^\n]s", *i);
    c = contalettere();
}while(c>dim);
}

Suppongo sia possibile fare ciò, però non capisco come, non ho capito cosa devo mettere come parametri di
C:
inserisci(???)
perchè è una struttura richiamata dentro una struttura, e con i puntatori non ho capito come si faccia
 

pabloski

Utente Èlite
2,868
916
Mi lascia perplesso il titolo. Funzione di funzione indica una composizione di funzioni. Ed ovviamente si può fare in tanti linguaggi, compreso il C. Nella soluzione, però, non vedo ombra di composizioni.

E il problema nemmeno si può risolvere tramite composizione.

Detto questo, ci sono varie soluzioni a quello che vuoi fare. L'importante è che l'input venga passato ad una o più funzioni di controllo e che un codice d'errore venga propagato a ritroso, qualora uno dei controlli fallisca. Ovviamente il codice d'errore deve pure far capire cos'è che è andato storto.

Dal codice, mi pare di capire che non ti sono chiari i puntatori, anche se vedo che li hai usati in riempiStruttura e inserisci. Anche se quello scanf mi fa capire che effettivamente non ti sono per niente chiari.

Riguardo i controlli, potresti semplicemente richiamare, una dietro l'altra, le funzioni che effettuano i controlli. Poi, per ogni chiamata, controlli il codice ricevuto ( successo o errore ). E' il metodo più semplice. Ma potresti usare un'implementazione basata su stream, che però ti costringe a passare in giro i puntatori alle funzioni di controllo e ovviamente dovresti saper usare i puntatori ad occhi chiusi.
 

Stefanokj

Utente Attivo
333
7
OS
Arch
Mi lascia perplesso il titolo. Funzione di funzione indica una composizione di funzioni. Ed ovviamente si può fare in tanti linguaggi, compreso il C. Nella soluzione, però, non vedo ombra di composizioni.

E il problema nemmeno si può risolvere tramite composizione.

Detto questo, ci sono varie soluzioni a quello che vuoi fare. L'importante è che l'input venga passato ad una o più funzioni di controllo e che un codice d'errore venga propagato a ritroso, qualora uno dei controlli fallisca. Ovviamente il codice d'errore deve pure far capire cos'è che è andato storto.

Dal codice, mi pare di capire che non ti sono chiari i puntatori, anche se vedo che li hai usati in riempiStruttura e inserisci. Anche se quello scanf mi fa capire che effettivamente non ti sono per niente chiari.

Riguardo i controlli, potresti semplicemente richiamare, una dietro l'altra, le funzioni che effettuano i controlli. Poi, per ogni chiamata, controlli il codice ricevuto ( successo o errore ). E' il metodo più semplice. Ma potresti usare un'implementazione basata su stream, che però ti costringe a passare in giro i puntatori alle funzioni di controllo e ovviamente dovresti saper usare i puntatori ad occhi chiusi.
Quindi potrei fare qualcosa di questo tipo:
C:
do {
printf("\n Inserisci indirizzo : ");

if (scanf("%512[^\n]s\n", soggetto->indirizzo) == 1) {   
        if(checkRezidenza(soggetto->indirizzo)) break;
       }
      printf("\ninput error, please retry.");
} while(1);
...

int checkResidenza(char* res) {   
      return checkStrLen(50,511,res); 
}

int checkStrLen(int min, int max, char* s) {  
      int len = strlen(s);
      return (len >= min) && (len <= max);
}

Il problema rimane che appesantisco troppo la funzione di input
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,221
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
In che senso? Cosa intendi di preciso con "appensantisco troppo la funzione di input"?
 

Stefanokj

Utente Attivo
333
7
OS
Arch
In che senso? Cosa intendi di preciso con "appensantisco troppo la funzione di input"?
Praticamente devo cercare di dividere il progetto il più " atomicamente" possibile. Essendoci nella struttura 3 inserimenti simili di stringhe (cambia solo la dimensione) allora devo fare una funzioncina apposita
 

pabloski

Utente Èlite
2,868
916
Praticamente devo cercare di dividere il progetto il più " atomicamente" possibile. Essendoci nella struttura 3 inserimenti simili di stringhe (cambia solo la dimensione) allora devo fare una funzioncina apposita

Beh, pure gli scanf devono essere uno per ogni campo della struct da popolare. Praticamente vuoi iterare automaticamente sui campi della struct, cosa che ti costringe a smanettare col preprocessore https://www.natecraun.net/articles/struct-iteration-through-abuse-of-the-c-preprocessor.html

E' una tematica alquanto complessa e le implementazioni sono molto fragili. Le uniche due cose che potresti fare sono:

1. usare un array per i campi della struct ( ma a questo punto usi un array e basta )
2. ti metti a giocare con l'aritmetica dei puntatori sulla struct ( cosa che ti costringere però a sapere a priori le dimensioni dei campi )

Il punto due si può semplificare usando dei puntatori come campi della struct e le stringhe verranno allocate dinamicamente nell'heap.

Onestamente tutto più complicato di quanto ottenibile seguendo la strada normale.
 

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

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili