ошибка сегментации при использовании fread и невозможность считывания данных из файла

#c

#c

Вопрос:

Здесь я хочу скопировать данные из файла enter_data и передать их функции insert (key, ключи), но я получаю ошибку сегментации и, более того, я не могу прочитать данные из файла

здесь классификатор представляет собой структуру, а packet_filter имеет структуру ip и udp, в которой я хочу ввести адрес IP-адреса src и dst, а также номер порта src и dst

     struct classifier
    {
        int key_node;
        struct packet_filter pktFltr;
        struct classifier *next;
    }__attribute__((packed));




    void addrule(struct classifier keys)
    {
            int key;
            FILE *fp;
            fp = fopen("enter_data","r");
            fread(amp;keys, sizeof (struct classifier), 3, fp);
            insert(key,keys);
            fclose(fp);
    }
  

                     file: enter_data

        key = 822;
        keys.key_node = 822;
        inet_aton("172.28.6.137", amp;(keys.pktFltr.ip.ip_src));
        inet_aton("172.28.6.10",amp;(keys.pktFltr.ip.ip_dst));
        keys.pktFltr.protocol.proto.uh_sport = ntohs(1032);
        keys.pktFltr.protocol.proto.uh_dport = ntohs(5000);
        keys.next = NULL;


        key = 522 ;
        keys.key_node = 522;
        inet_aton("172.28.6.87", amp;(keys.pktFltr.ip.ip_src));
        inet_aton("172.28.6.110",amp;(keys.pktFltr.ip.ip_dst));
        keys.pktFltr.protocol.proto.uh_sport = ntohs(1032);
        keys.pktFltr.protocol.proto.uh_dport = ntohs(5010);
        keys.next = NULL;

        key = 522 ;
        keys.key_node = 522;
        inet_aton("172.28.6.87", amp;(keys.pktFltr.ip.ip_src));
        inet_aton("172.28.6.110",amp;(keys.pktFltr.ip.ip_dst));
        keys.pktFltr.protocol.proto.uh_sport = ntohs(1032);
        keys.pktFltr.protocol.proto.uh_dport = ntohs(5011);
        keys.next = NULL;
  

Комментарии:

1. Вы пытались запустить отладчик для этого кода, чтобы определить, где именно ошибка в сегментации?

2. Если вторая запись является вашим файлом, то этот код не будет работать. Вы пытаетесь выполнить чтение с использованием двоичной сериализации, но ваш файл является текстовым файлом.

Ответ №1:

Это не сработает, потому что вы пытаетесь прочитать двоичный файл, в то время как ваш файл является текстовым.

Второе — вам нужно проверить, fp есть NULL ли после попытки открыть файл — просто совет.

В-третьих, даже если файл был двоичным, это не сработало бы, поскольку

 fread(amp;keys, sizeof (struct classifier), 3, fp);
  

должно быть

 //                                      vvv
fread(amp;keys, sizeof (struct classifier), 1, fp);
  

As keys не является массивом, и вам нужно читать только по блоку.

Комментарии:

1. Не уверен, почему вы говорите «просто совет». Важно убедиться, что fopen выполняется успешно. Неспособность проверить это приводит к неработоспособности программы.

2. @William — просто не хотел показаться «слишком сложным» : D Всегда программист обязан проверять код возврата используемых функций (если таковые имеются, конечно)

Ответ №2:

Похоже, вы не выделяете достаточно места для своих 3 ключей.

 void addrule(struct classifier keys)
{
....
    fread(amp;keys, sizeof (struct classifier), 3, fp);    // Here you read 3 keys and put into amp;keys, but you gave only one struct to your method
  

Возможно, с циклом, считывающим по одному ключу в каждом :

 void addrule(struct classifier keys)
{
....
    while fread(amp;keys, sizeof (struct classifier), 1, fp)
    {
        insert(key,keys);
    }
    fclose(fp);
}
  

Комментарии:

1. Не только. Это сработало бы для двоичных файлов, и кажется, что это текстовый файл.

2. да, у меня есть только одна структура, но я должен вводить разные данные в одну и ту же структуру и продолжать передавать структуру, как я могу это сделать.

3. @sandeep: я отредактировал свой ответ с помощью цикла, чтобы вставлять ключи один за другим