Search code examples
cfileinputdefensive-programming

validating content of input file


I have this defensive-programming issue that I don't really know how to solve.

I have this function that takes file path and size of table (rows / columns count) as arguments and I'm looking for better way of validating the input file. I assume that arguments of this function are always correct. size represents the "smaller side" of the table that is stored in file:

For example :

1 2 3 4 
5 6 7 8 

size = 2 is correct while

1 2 3 4 5
5 6 7 8 9

size = 2 is incorrect

I'd also like to be able to reject the files like this

1 2 3 4 5 6 7 8

size = 2 (which is accepted through fscanf)

Another type of file I'd like to be able to reject is

1 2 3
4 5 6

size = 2

As for now my only security is checking if the elements of the file are really numbers.

Here is the code I've done so far :

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);
}

I don't really where and how to start, I'm not really proficient in C and there seems to exist a lot of functions and mechanisms to do what I want but they all seem very complex and some are actually longer than the code I provided.

If anyone can point me in the right direction that'd be great.


Solution

  • Your for loop could look like this:

    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;
        }
    }
    

    Also note that assert(data); should be replaced with something like this:

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