Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 25
  1. #1

    [C] verificare tipo dato in lettura

    Buongiorno a tutti, mi trovo a dover leggere da file un vettore di double la cui dimensione è scritta nella prima riga del file. Ecco un esempio di file:

    codice:
    10
    2.00
    2.00
    3.00
    2.00
    4.00
    3.00
    5.00
    1.00
    1.00
    4.00
    devo verificare la bontà del file, ossia effettuare un controllo sul tipo del primo dato: in parole povere, verificare che 10 sia effettivamente un intero e non qualcos'altro, come un carattere o semplicemente un intero con segno.

    Quello che faccio ora è di andare a leggere la prima riga con fscanf, ma basta sostituire "10" con "xx" per andare in segmentation fault.

    Qualcuno ha qualche suggerimento?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Leggi la riga con fgets e poi esamina il contenuto della stringa letta.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Una cosa del genere?

    codice:
    ...
    char stringa[5], temp[5];
    temp = fgets(stringa, sizeof( int ), fPtr);
    
    /* verifico che temp sia un int (con atoi va bene?) */
    
    int size = atoi(temp);
    
    // ora basta controllare che size sia positivo?
    
    /* e poi continuo a leggere il resto del file */
    
    		while ( !feof(fPtr) ) {
    			fscanf(fPtr, "%lf", &v[i]);
    			i++;
    		}
    		for(i=0; i<size; i++)
    			printf("%.2f\n",v[i]);
    ...

  4. #4
    In alternativa puoi leggere normalmente con fscanf, verificando il valore restituito (se corrisponde con il numero di campi specificati l'operazione è andata a buon fine) ed eventualmente controllando che il carattere successivo sia un '\n'.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    atoi non ti garantisce che non ci siano altre cose nella stringa.

    Se proprio vuoi esserne sicuro, devi controllare che ogni carattere della stringa sia quello che ti aspetti ...

    Ad esempio, se nella stringa c'è

    20xxx

    il valore di atoi sarà 20 anche se ci sono quelle xxx ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    verificando il valore restituito
    devi controllare che ogni carattere della stringa sia quello che ti aspetti
    è proprio questo il punto...come faccio questa verifica? Si potrebbe controllare che il carattere sia compreso tra '0' e '9', ma se il numero è composto da più cifre?
    Mi viene in mente che una buona soluzione sarebbe scrivere un'espressione regolare del tipo:
    [1-9][0-9]*\n
    ma non ho mai usato espressioni regolari in C !
    possibile che non esista una funzione che data una serie di caratteri ti dica se questo è un numero positivo o no?

  7. #7
    Non è difficile: controlla il valore restituito da fscanf:
    codice:
    unsigned int dimensioni;
    if(fscanf(file,"%u",&dimensioni)!=1)
    {
        /* errore */
    }
    Volendo anche essere sicuri che sia arrivato a fine riga:
    codice:
    unsigned int dimensioni;
    if(fscanf(file,"%u",&dimensioni)!=1 || fgetc(file)!='\n')
    {
        /* errore */
    }
    ungetc('\n',file);
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Grazie mille!

    Mi sono perso in un bicchier d'acqua! Dimentico sempre che molte funzioni su file, come scanf, restituiscono il numero di caratteri letti! Mentre invece ignoravo la funzione ungetc, che reinserisce un carattere nello stream!

    Un'ultima cosa: per verificare che il contenuto del file sia coerente, devo assicurarmi che la dimensione dichiarata in prima riga sia poi effetivamente quella del file. Questo si fa facilmente scandendo tutto il file e contando le righe.
    Il problema è che per file molto grandi questa operazione potrebbe divenire troppo onerosa; come posso sapere quanti record contiene il file senza andarmelo a scandire tutto?

  9. #9
    Originariamente inviato da dosdosdos
    Grazie mille!

    Mi sono perso in un bicchier d'acqua! Dimentico sempre che molte funzioni su file, come scanf, restituiscono il numero di caratteri letti!
    Occhio che fscanf non restituisce il numero di caratteri letti, ma il numero di campi letti e convertiti correttamente.
    Il problema è che per file molto grandi questa operazione potrebbe divenire troppo onerosa; come posso sapere quanti record contiene il file senza andarmelo a scandire tutto?
    Io mi limiterei a leggere finché non trovi eof o non leggi il numero di elementi specificato all'inizio. Se il file finisce prima di aver letto il numero di elementi specificato, allora il file è corrotto; se ce ne sono di più (condizione che effettivamente non andiamo a controllare), pace, non ci interessano, non starei a farmi troppi problemi.
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Originariamente inviato da MItaly
    Occhio che fscanf non restituisce il numero di caratteri letti, ma il numero di campi letti e convertiti correttamente.

    Io mi limiterei a leggere finché non trovi eof o non leggi il numero di elementi specificato all'inizio. Se il file finisce prima di aver letto il numero di elementi specificato, allora il file è corrotto; se ce ne sono di più (condizione che effettivamente non andiamo a controllare), pace, non ci interessano, non starei a farmi troppi problemi.
    Il problema è che devo fare questo controllo perchè questi file devo utilizzarli su un algoritmo parallelo (con MPI) e devo essere sicuro del numero di righe per poterle partizionar ein modo corretto. Inoltre il file avrà molte molte righe!

    Avevo pensato a lavorare con la dimensione del file: se so a priori quanti Byte è lungo il file potrei dividere tale grandezza con la dimensione dei campi riga, ma ho qualche problema a capire come posso determinare la grandezza totale del file a priori.

    Un'ultima cosa: il codice precedente lancia correttamente un errore se al posto dell'intero della dimensione si scrive un carattere, ma non riesce a gestire un intero negativo.
    Scrivendo -10 al posto di 10 ottengo:

    Il vettore contiene 4294967286 elementi.
    Segmentation fault

    ...ma è possibile che converta automaticamente il numero in unsigned?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.