Значение, присваиваемое автоматически массиву указателей - PullRequest
0 голосов
/ 06 июня 2019

Я делаю проект, в котором мне нужно реализовать массив указателей на структуру!Структура содержит слово, его перевод и указатель на следующее!Итак, я должен создать связанный список, где указатель головы находится в одной из ячеек массивов!Я инициализирую массив в main значениями NULL!После этого мне нужно прочитать слово из файла, а затем выделить структуру, в которую я поместил слово read и его перевод, который также находится в файле.Структура файла выглядит следующим образом:

hello;bonjour

Существует функция с именем hash_string (word), которая генерирует индекс от 0 до размера массива-1.Так что для слова привет, я получаю индекс 2. Я вставляю это слово и его перевод в массив с помощью этой функции:

void remplissage_hachage (cellule_t **tabMajeur,FILE *fichier)
{
char  string1[20];
cellule_t *copy;
unsigned int indice;
int boolean = 0;
char *string2, *string3;
cellule_t *c;

while(fgets(string1,100,fichier) != NULL)
{

    string2 = strtok(string1,";");
    string3 = strtok(NULL,";"); 
    printf("string2: %s\n",string2);
    printf("string3: %s\n",string3);

    if(tabMajeur[2] != 0)
    {
        printf("Adresse 2 : %s\n",tabMajeur[2]->mot);

    }

    if(boolean != 1  && tabMajeur[2] == 0) 
    {    
        copy = tabMajeur[2];
        tabMajeur[2] = creationCellule(string2,string3);
        tabMajeur[2]->suivant = copy;    
    }
}
}

Вставка выполняется правильно, но когда я читаю другое слово, например

bye;au revoir

hash_string также дает индекс = 2, и теперь мне нужно создать связанный список, поместив это значение в заголовок связанного списка и передав привет в качестве второго элемента.Проблема в том, что без вставки массив [2] дает result = bye, а не hello, поэтому он немедленно перезаписывает слово hello.Я не понимаю, как это все возможно?

Я также помещаю структуру и основную функцию, чтобы показать вам, ребята, как я инициализирую массив:

typedef struct cell{

char *mot;
char *traduction;
struct cell *suivant;


}cellule_t;


int main()
{


    cellule_t **tabMajeur;
    tabMajeur = malloc(HASH_MAX * sizeof(cellule_t *));
    memset(tabMajeur,0 ,HASH_MAX);
    FILE * file = fopen("fichier.txt","r");
    remplissage_hachage(tabMajeur,"fichier.txt");

}

Файл выглядит так:

 hello;bonjour
 bye;au revoir

Огромное спасибо заранее !Я знаю, что текст длинный, но я хотел объяснить все, чтобы было понятно!

1 Ответ

0 голосов
/ 06 июня 2019

у вас есть несколько проблем в вашем коде:

char  string1[20];
...
while(fgets(string1,100,fichier) != NULL)

fgets может записывать из string1 с неопределенным hebavior, изменить размер string1 до 100, чтобы иметь больше места и в любом случае использовать sizeof :

char  string1[100];
...
while(fgets(string1, sizeof(string1),fichier) != NULL)

In main

remplissage_hachage (tabMajeur, "fichier.txt");

должно быть

remplissage_hachage(tabMajeur,file); 

потому что remplissage_hachage получает FILE*, а не имя файла

Если я сделаю предыдущие исправления и добавлю отсутствующие определения

#define HASH_MAX 10

cellule_t * creationCellule(char * s1, char * s2)
{
  cellule_t * r = malloc(sizeof(cellule_t));

  r->mot = strdup(s1);
  r->traduction = strdup(s2);
  r->suivant = NULL;
  return r;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall c.c
c.c: In function ‘remplissage_hachage’:
c.c:33:12: warning: unused variable ‘c’ [-Wunused-variable]
 cellule_t *c;
            ^
c.c:30:14: warning: unused variable ‘indice’ [-Wunused-variable]
 unsigned int indice;
              ^~~~~~
pi@raspberrypi:/tmp $ ./a.out
string2: hello
string3: bonjour

string2: bye
string3: au revoir

Adresse 2 : hello
pi@raspberrypi:/tmp $ 

как и ожидалось

проблема в том, что без вставки массив [2] дает результат = пока, а не привет, поэтому он сразу же перезаписывает слово привет. Я не понимаю, как все это возможно

это означает, что вы не дублируете строки, а делаете что-то подобное:

cellule_t * creationCellule(char * s1, char * s2)
{
  cellule_t * r = malloc(sizeof(cellule_t));

  r->mot = s1;
  r->traduction = s2;
  r->suivant = NULL;
  return r;
}

, поэтому вы всегда сохраняете указатели в string1 в tabMajeur , поэтому во второй раз, когда вы печатаете значение, используется новое содержимое string1

Вы должны сделать

  r->mot = strdup(s1);
  r->traduction = strdup(s2);

или если у вас нет strdup

  r->mot = malloc(strlen(s1) + 1);
  strcpy(r->mot, s1);
  r->traduction = malloc(strlen(s2) + 1);
  strcpy(r->traduction, s2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...