проверка содержимого входного файла - PullRequest
0 голосов
/ 21 февраля 2012

У меня есть проблема с защитным программированием, которую я не знаю, как решить.

У меня есть эта функция, которая принимает путь файла и размер таблицы (количество строк / столбцов) в качестве аргументов, и я ищу лучший способ проверки входного файла. Я предполагаю, что аргументы этой функции всегда верны. size представляет «меньшую сторону» таблицы, которая хранится в файле:

Например:

1 2 3 4 
5 6 7 8 

размер = 2 правильно, пока

1 2 3 4 5
5 6 7 8 9

размер = 2 неверно

Я также хотел бы иметь возможность отклонить файлы, подобные этому

1 2 3 4 5 6 7 8

size = 2 (который принимается через fscanf)

Другой тип файла, который я бы хотел отклонить, это

1 2 3
4 5 6

размер = 2

На данный момент моя единственная защита - проверка, действительно ли элементы файла являются числами.

Вот код, который я сделал до сих пор:

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

На самом деле я не знаю, с чего и как начать, я не очень опытный в C, и, кажется, существует множество функций и механизмов, чтобы делать то, что я хочу, но все они кажутся очень сложными, а некоторые на самом деле длиннее, чем код, который я предоставил.

Если кто-нибудь может указать мне правильное направление, это было бы здорово.

Ответы [ 3 ]

1 голос
/ 21 февраля 2012

Ваш цикл for может выглядеть так:

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

Также обратите внимание, что assert(data); следует заменить на что-то вроде этого:

if (!data)
{
    printf("Error while openning the file [filePath=\"%s\"].\n", filePath);
    cleanExit();
}
1 голос
/ 21 февраля 2012

Вы не можете легко обнаружить концы строк в scanf(), поэтому использование этого напрямую не будет соответствовать вашим критериям.

Возможно, вам нужно прочитать целые строки (fgets() или, возможно, * 1005).*), а затем обрабатывать каждую строку по очереди.Для обработки строки можно использовать sscanf(), и вы можете использовать директиву %n.В общих чертах это сводится к:

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...
0 голосов
/ 21 февраля 2012

Вы также можете рассчитать контрольную сумму всего файла.Вопрос в том, насколько серьезно вы к этому относитесь.Легко создать контрольную сумму xor, но это не совсем безопасно от столкновений.Лучше всего использовать что-то вроде ша-1, если это важно.

...