Domanda

Ho questo problema di programmazione difensiva che non so davvero come risolvere.

Ho questa funzione che prende il percorso e le dimensioni del file della tabella (contano / colonne contano) come argomenti e sto cercando un modo migliore per convalidare il file di input. Presumo che gli argomenti di questa funzione siano sempre corretti. size rappresenta il "lato più piccolo" della tabella memorizzata nel file:

Per esempio :

1 2 3 4 
5 6 7 8 

dimensione = 2 è corretto mentre

1 2 3 4 5
5 6 7 8 9

dimensione = 2 non è corretto

Vorrei anche poter rifiutare i file in questo modo

1 2 3 4 5 6 7 8

dimensione = 2 (che è accettato tramite fscanf)

Un altro tipo di file che vorrei poter rifiutare è

1 2 3
4 5 6

dimensione = 2

Per ora la mia unica sicurezza è controllare se gli elementi del file sono davvero numeri.

Ecco il codice che ho fatto finora:

void import(float** table, int size, char* path)
{
    FILE* data = fopen(path, "r");
    assert(data);
    int i,j;
    int st;

    for (i=0; i<size; i++)
    {
        for(j=0; j<(size*2)-1; j++)
        {
            st = fscanf(data, "%f", &table[i][j]);
            if (!st)
            {
                printf("Error while importing the file.\n");
                fclose(data);
                return -1;
            }
        }
    }
    fclose(data);
}

Non sono proprio dove e come iniziare, non sono davvero abile in C e sembra che ci siano molte funzioni e meccanismi per fare quello che voglio, ma sembrano tutti molto complessi e alcuni sono in realtà più lunghi del codice I fornito.

Se qualcuno può indicarmi nella giusta direzione, sarebbe fantastico.

È stato utile?

Soluzione

Il tuo loop potrebbe apparire così:

char line[1000], *token;
for (i = 0; i < size; i++) // for each line
{
    if (fgets(line, 1000, data) != NULL) // read line
    {
        token = strtok (line," ");
        for (j = 0; j < (size * 2) - 1; j++) // for each number from line
        {
            if (sscanf(token, "%f", &table[i][j]) <= 0)
            {
                // there are columns missing:
                printf("Error while importing the file.\n");
                fclose(data);
                return -1;
            }
            token = strtok (NULL," ");
        }
    }
    else
    {
        // there are rows missing:
        printf("Error while importing the file.\n");
        fclose(data);
        return -1;
    }
}

Nota anche che assert(data); dovrebbe essere sostituito con qualcosa di simile:

if (!data)
{
    printf("Error while openning the file [filePath=\"%s\"].\n", filePath);
    cleanExit();
}

Altri suggerimenti

Non puoi facilmente rilevare le estremità delle righe in scanf(), quindi usarlo direttamente non soddisferà i tuoi criteri.

Probabilmente devi leggere intere righe (fgets() o forse getline()), quindi elabora ogni riga a turno. L'elaborazione della linea può utilizzare sscanf(), e puoi usare il %n Direttiva anche. In contorno, questo si riduce a:

for (line_num = 0; line_num < size; line_num++)
{
    ...read line from file into buffer line, checking for EOF...
    start = line;
    for (i = 0; i < 2 * size; i++)
    {
        if (sscanf(start, "%f%n", &value, &offset) != 1)
            ...ooops - short line or non-numeric data...
        else
        {
            start += offset;
            table[line_num][i] = value;
        }
    }
}
...check that there's no clutter after the last expected line...

È inoltre possibile calcolare un checksum dell'intero file. La domanda è quanto sei serio. È facile creare un checksum XOR, ma non è davvero sicuro contro le collisioni. Il meglio è probabilmente usare qualcosa come sha-1 se è importante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top