通过充满单词的数组(从文件中检索)来操纵文件的单词

时间:2019-03-10 21:24:30

标签: c

我用otherItems浏览了文件。 我将fgets返回的句子标记为fgets以检索单词 我将单词保存在strtok

的数组中
char*

现在,我要遍历包含文件单词的while (fgets(chaine, TAILLE_MAX, fichier) != NULL) { chainetoken = strtok(chaine, " "); while (chainetoken != NULL) { tableau[i] = chainetoken; chainetoken = strtok (NULL, " "); i++; }// it works wel } printf("%d \n", i); char*)数组,以便查找用户输入的单词并找到前面和后面的2个单词在文件中关注

tableau[i]

1 个答案:

答案 0 :(得分:2)

您有三个错误

1)in

while (fgets(chaine, TAILLE_MAX, fichier) != NULL) 
{
   chainetoken=strtok(chaine," ");
   while (chainetoken != NULL)
   {              
      tableau[i]= chainetoken;
      chainetoken = strtok (NULL," ");
      i++;
    }// it works wel
}

您需要保存 strtok 的结果的副本 strdup ),否则,您总是要保存指向内部的指针每个 fgets

修改过的chaine

2) strtok 的分隔符必须为“ \ n”,否则'\ n'是 strtok

返回的结果的一部分

3)in

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 而不是 table

j

附加说明:在 while 中,您需要检查 i 是否达到 table 中的条目数,否则您就有写风险出来。


(编辑以解释为什么需要复制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 返回 chaines 的子字符串,并在每次返回非null指针时对其进行修改以添加null char,因此(我在null字符下方用' @')

  • fgets 读取第一行,chaine_包含“ 1234 5678 \ n @”
  • strtok 用空字符替换“ 1234 5678 \ n @”中的空格,并返回 chaine 的地址(“ 1234 @ 5678 \ n @”)为记忆在tableau[0]
  • strtok 用空字符替换'\ n',并返回存储在tableau[1] chaine + 5 (“ 5678 @”) >
  • 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 @”) 1}}
  • strtok 用空字符替换'5'之后的空格,并返回存储在{{1中的 chaine + 5 (“ 45 @ 678 \ n @”) }}
  • strtok 用空字符替换'\ n',并返回存储在tableau[3]中的 chaine + 8 (“ 678 @”)
  • 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 的结果的原因:

tableau[4]

编译和执行:

tableau[5]