首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过一个充满单词的数组操作文件的单词(从文件中检索)

通过一个充满单词的数组操作文件的单词(从文件中检索)
EN

Stack Overflow用户
提问于 2019-03-11 05:24:30
回答 1查看 44关注 0票数 1

我用fgets浏览了这个文件。我使用strtok标记fgets返回的句子,以检索我将单词保存在char*数组中的单词

代码语言:javascript
复制
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* (tableau[i])数组,以便找到用户输入的单词,并在文件中找到前后两个单词

代码语言:javascript
复制
printf("words to find?\n");
scanf("%s", mot_recherche);

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)!!!!
EN

回答 1

Stack Overflow用户

发布于 2019-03-11 06:15:06

您有三个错误

1)在

代码语言:javascript
复制
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)在

代码语言:javascript
复制
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)!!!!

你看的是tableau的条目i而不是j

补充说明:在此期间,您需要检查我是否达到了tableau中的条目数量,否则您将冒着将其写出来的风险。

(编辑以解释为什么需要复制strtok的结果)

让该程序使用strtok作为您的用户(没有复制):

代码语言:javascript
复制
#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]);
  }

编译和执行:

代码语言:javascript
复制
/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读取第一行,strtok包含"1234 5678\n@"
  • strtok用空字符替换"1234 5678\n@“中的空格,并返回在tableau[0]
  • strtok中存储的链的地址("1234@5678\n@")用空字符替换'\n‘,并返回存储在tableau[1]
  • the中的链+5 ("5678@")下一次调用chaine_返回空pointer
  • fgets读取下一行并修改链以包含"1 23 45 678\n@”H218tableau[2]
  • strtok中存储的字符串的地址(“1@2 3045678\n@”)替换在tableau[3]
  • strtok中存储的空格,并返回在tableau[4]
  • strtok中存储的字符串+2(“23@45678\n@”)替换在tableau[4]
  • strtok中存储的字符code>+5 ("45@678\n@")替换
  • 中存储的'\n‘通过空字符并返回存储在tableau[5]
  • strtok中的chaine +8 ("678@"),返回空指针

所以现在chaine包含"1@23@45@678@“,tableau中的指针是:

printf产生'1‘而不是'1234’expected

  • tableau1 = chaine+5:" 45 @678@",

  • 产生45而不是'5678‘'23'

  • tableau4 = chaine:"1@23@45@678@",产生'1'
  • tableau3 = chaine+2:"23@45@678@",printf产生’23‘
  • tableau4=chaine+5:"45@678@",printf产生'45'
  • tableau5 = chaine+8:"678@",printf产生'678'

这就是为什么需要复制strtok的结果:

代码语言:javascript
复制
#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 */
    }
  }
}

编译和执行:

代码语言:javascript
复制
/tmp % gcc -pedantic -Wextra f.c
/tmp % cat in
1234 5678
1 23 45 678
/tmp % ./a.out
'1234'
'5678'
'1'
'23'
'45'
'678'
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55092551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档