繁体   English   中英

检查C中的txt文件中是否存在数组的单词

[英]Check if words of an array exist in a txt file in C

我有很多话:

const char *words[3]={cat,dog,snake,bee};

和这样的txt文件:

apple tree day night story bee oil lemons get fight 234 meow woof safari  
jazz stuff what is dog fight street snake garden glass house bee question                 
foot head 29191 43493 == 

(我们不知道该文件有多少行)

我想检查整个文件,并且每次我找到数组中的一个单词以打印该单词并在找到它的行中打印。

我在比较时遇到麻烦。 我的想法是将文件的每个单词保存到一个数组中,然后将每个单词与单词数组中的单词进行比较。 但是我不能那样做。 我有这个:

FILE *f;
const char *arr;
f=fopen("test.txt","r");
while(fscanf(f,"%s",arr)!EOF)

我真的不知道在这里写什么,以便将文件分成单词。

请对我好一点,我只是想学习。

您提供的代码段中存在几个问题:

const char *words[3]={cat,dog,snake,bee};

在这里,您声明了一个由3个元素组成的数组,但是您有4个初始化程序。 而且您忘了在引号之间加上单词。

在这里,您使用fscanf读取arr ,但是您没有分配内存, arr没有初始化,您可能打算写char arr[200] ,最大字长为200。

FILE *f;
const char *arr;
f=fopen("test.txt","r");
while(fscanf(f,"%s",arr)!EOF)

您希望以此为基础,但仍然需要改进房间形式:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char *words[] = { "cat", "dog", "snake", "bee" };

int main()
{
  char line[200];   // maximum line size is 200
  size_t len = 0;

  FILE *f;
  f = fopen("test.txt", "r");

  if (f == NULL)
  {
    printf("Can't open file\n");
    return 1;
  }

  int line_no = 0;
  while (fgets(line, sizeof line, f))
  {
    ++line_no;

    // (sizeof words)/sizeof *words is the the number of words in the words array
    for (int i = 0; i < (sizeof words)/sizeof *words; i++) 
    {
      if (strstr(line, words[i]) != NULL)
      {
        printf("found %s in line %d\n", words[i], line_no);
      }
    }
  }

  fclose(f);
}

您正在使用fscanf()从文件中读取单词,这不是最好的方法。 您应该使用getline(3)fgets(3)来读取文件的每一行。

此外,此行:

const char *words[3]={cat,dog,snake,bee}; 

需要能够容纳4个char*指针,而不是3个。您还需要在这些字符串文字中包含引号。 这是执行此操作的另一种方法:

const char *words[] = {"cat", "dog", "snake", "bee"};

然后,要获取此数组的大小,只需使用sizeof(x) / sizeof(x[0])

此外,在此代码段中:

FILE *f;
const char *arr;
f=fopen("test.txt","r");
while(fscanf(f,"%s",arr)!EOF)

您在未初始化的指针上使用fscanf() ,这会导致许多问题。 如果希望使用指针,则可能需要使用malloc(3)在堆上动态分配arr 如果您不想这样做,只需声明一个VLA,例如char arr[200] 而且fscanf()返回扫描的项目数,因此fscanf(f,"%s",arr)!=EOF必须替换为fscanf(f,"%s",arr)==1 ,以确保一个单词一次被读取。

注意:您还应该检查FILE *f是否正确打开,因为它在错误时可以返回NULL

我在比较时遇到麻烦。 我的想法是将文件的每个单词保存到一个数组中,然后将每个单词与单词数组中的单词进行比较。

正如其他人提到的使用strstr(3) ,另一种可能的选择是使用strtok(3)解析行中的每个单词,然后使用strcmp(3)words[i]与从文件中解析出的单词进行比较。 如果将来words[]变得更大,我建议使用二进制搜索而不是线性搜索来比较单词。 这样可以将搜索时间从O(n)缩短到O(logn)

这是我之前编写的一些(修改后的)代码,其功能类似:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ARRAYSIZE(x) (sizeof x / sizeof x[0])

int main(void) {
    const char *words[] = {"cat", "dog", "snake", "bee"};
    FILE *fptr;
    char *line = NULL, *word = NULL;
    const char *delim = " \n";
    size_t len = 0, lineno = 0;
    ssize_t read;

    fptr = fopen("somewords.txt", "r");
    if (fptr == NULL) {
        fprintf(stderr, "Error reading file\n");
        exit(EXIT_FAILURE);
    }

    while ((read = getline(&line, &len, fptr)) != -1) {
        lineno++;
        word = strtok(line, delim);
        while (word != NULL) {
            for (size_t i = 0; i < ARRAYSIZE(words); i++) {
                if (strcmp(word, words[i]) == 0) {
                    printf("Found matched word: %s, Line number: %zu\n", word, lineno);
                }
            }
            word = strtok(NULL, delim);
        }
    }

    free(line);

    fclose(fptr);

    return 0;
}

使用getline和strstr

char *line = NULL;
size_t len = 0;
ssize_t read;

int line_no = 0;
while ((read = getline(&line, &len, f)) != -1) 
{
    ++line_no;
    for (int i = 0; i < 3; i++) {
        if (strstr(line, words[i]) != null) 
        {
            // if matched
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM