У вас есть три ошибки
1) в
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
{
chainetoken=strtok(chaine," ");
while (chainetoken != NULL)
{
tableau[i]= chainetoken;
chainetoken = strtok (NULL," ");
i++;
}// it works wel
}
вам нужно сохранить копию ( strdup ) результата strtok , в противном случае вы всегда сохраняете указатель, указывающий внутри chaine который изменяется каждым fgets
2) разделители для strtok должны быть "\ n", иначе '\ n' является частью результата, возвращаемого strtok
3) в
for (j=0; j<i; j++)
{
printf ("tableau %d.mot %s \n",i,tableau[i]);//tableau[0]=last word of the file
if (strcmp(mot_recherche,tableau[i])==0)
printf("this word exist \n");
}//doesn't work,it save only the last word of the array(of the file)!!!!
вы смотрите на запись i вместо j из таблицы
Дополнительное замечание: в в то время как вам необходимо проверить, достигнет ли i количества записей в таблице , иначе вы рискуете выписать из него .
(изменить, чтобы объяснить, почему необходимо дублировать результат strtok)
Имея эту программу, используя strtok как вы (без дублирования):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE * fichier = fopen("in", "r");
if (fichier != NULL)
{
#define TAILLE_MAX 32
char chaine[TAILLE_MAX];
char * chainetoken;
char * tableau[16];
int i = 0, j;
while ((fgets(chaine, TAILLE_MAX, fichier) != NULL) &&
(i != sizeof(tableau)/sizeof(tableau[0])))
{
chainetoken=strtok(chaine," \n");
while (chainetoken != NULL)
{
tableau[i]= chainetoken;
chainetoken = strtok (NULL," \n");
i++;
}
}
fclose(fichier);
for (j = 0; j != i; ++j)
printf("'%s'\n", tableau[j]);
}
Компиляция и исполнение:
/tmp % gcc -pedantic -Wextra f.c
/tmp % cat in
1234 5678
1 23 45 678
/tmp % ./a.out
'1'
'45'
'1'
'23'
'45'
'678'
ожидаемый результат - 1234 5678 1 23 45 678
, но это не тот случай, и только содержание второй строки in
является правильным (потому что это последняя строка файла).
strtok возвращает подстроки цепочек , изменяя его так, чтобы он добавлял нулевой символ каждый раз, когда он возвращает ненулевой указатель, поэтому (я указываю под нулевым символом с помощью '@' )
- fgets читает первую строку, chaine_ содержит "1234 5678 \ n @"
- strtok заменяет пробел в "1234 5678 \ n @" нулевым символом и возвращает адрес chaine ("1234 @ 5678 \ n @"), который запоминается в
tableau[0]
- strtok заменяет '\ n' нулевым символом и возвращает цепочку + 5 ("5678 @"), запомненную в
tableau[1]
- следующий следующий вызов strtok возвращает нулевой указатель
- fgets читает следующую строку и изменяет chaine на «1 23 45 678 \ n @»
- strtok заменяет пробел после '1' нулевым символом и возвращает адрес chaine ("1 @ 23 045 678 \ n @"), запомненный в
tableau[2]
- strtok заменяет пробел после '3' нулевым символом и возвращает chaine + 2 ("23 @ 45 678 \ n @"), запомненные в
tableau[3]
- strtok заменяет пробел после '5' на нулевой символ и возвращает chaine + 5 ("45 @ 678 \ n @"), запоминаемый в
tableau[4]
- strtok заменяет '\ n' нулевым символом и возвращает chaine + 8 ("678 @"), запомненные в
tableau[5]
- strtok вернуть нулевой указатель
теперь chaine содержит "1 @ 23 @ 45 @ 678 @", а указатели в table * :
- tableau [0] = chaine = "1 @ 23 @ 45 @ 678 @", printf выдает «1» вместо ожидаемого «1234»
- tableau [1] = chaine + 5 : "45 @ 678 @", печать дает 45, а не 5678, ожидаемое
- tableau [2] = chaine : «1 @ 23 @ 45 @ 678 @», printf выдает «1»
- tableau [3] = chaine + 2 : «23 @ 45 @ 678 @», printf выдает «23»
- tableau [4] = chaine + 5 : "45 @ 678 @", printf выдает 45
- tableau [5] = chaine + 8 : «678 @», printf выдает «678»
именно поэтому необходимо дублировать результат strtok :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE * fichier = fopen("in", "r");
if (fichier != NULL)
{
#define TAILLE_MAX 32
char chaine[TAILLE_MAX];
char * chainetoken;
char * tableau[16];
int i = 0, j;
while ((fgets(chaine, TAILLE_MAX, fichier) != NULL) &&
(i != sizeof(tableau)/sizeof(tableau[0])))
{
chainetoken=strtok(chaine," \n");
while (chainetoken != NULL)
{
tableau[i]= strdup(chainetoken);
chainetoken = strtok (NULL," \n");
i++;
}
}
fclose(fichier);
for (j = 0; j != i; ++j) {
printf("'%s'\n", tableau[j]);
free(tableau[j]); /* to avoid memory leak */
}
}
}
Компиляция и исполнение:
/tmp % gcc -pedantic -Wextra f.c
/tmp % cat in
1234 5678
1 23 45 678
/tmp % ./a.out
'1234'
'5678'
'1'
'23'
'45'
'678'