如何计算文件中的特定单词?

时间:2013-12-30 11:26:41

标签: c

我正在尝试创建一个读取文件并计算特定单词的c程序。

我尝试了这段代码,但我没有得到任何结果:

#include<stdio.h>
#include<stdlib.h>
void main
{
  File *fp = fopen("file.txt","r+");
  int count =0;
  char ch[10]; 

  while((fgetc(fp)!=NULL)
   {
     while((fgetc(fp)!=NULL)
      {
        if((fgets(ch,3,fp))=="the" || (fgets(ch,3,fp))=="and")
         count++;
      }
   }
   printf("%d",count);
}

8 个答案:

答案 0 :(得分:1)

当您一次以3个块的形式获取数据时,您假设两个单词“the”和“and”在3个字符边界上对齐。一般来说,情况并非如此。

您还需要使用strncmp来比较字符串。

作为第一篇评论,我会逐行阅读,并在每行搜索您想要的单词。

我也不确定你有两个嵌套while循环的意图。

答案 1 :(得分:1)

您无法将字符串指针与等于运算符进行比较,您必须使用strcmp函数。

您的代码还存在其他问题。对于一次,fgetc调用不会在错误或问题上返回NULL,而是EOF。否则它返回从文件中读取的字符。

此外,您的两个fgets条件将导致读取两个“行”(尽管您读取的每个“行”只有两个字符)。

答案 2 :(得分:1)

fgets(ch, 3, fp)使您读取2个字符加上空终止符,如果您想要读取3个字符而使用空终结符fgets(ch, 4, fp)。此外,您需要使用strcmp来比较字符串。

此外,那些循环的所有内容是什么?

答案 3 :(得分:0)

if((fgets(ch,3,fp))==“the”||(fgets(ch,3,fp))==“和”)

以上几行完全没用。 fgets(ch,3,fp)将你的单词从文件中获取到ch [10]。但你不能用==来比较它。 我要做的是使用strcmp并在fgets中给出大小4(永远不要忘记\ o)

答案 4 :(得分:0)

你必须使用strcmp()来比较两个字符串。不是关系运营商。

答案 5 :(得分:0)

刚出头(也许不是最佳方式,但应该很容易阅读和理解):

#define WHITE_SPACE(c) ((c)==' ' || (c)=='\r' || (c)=='\n' || (c)=='\t'))

int CountWords(const char* fileName,int numOfWords,const char words[])
{
    int count = 0;
    FILE* fp = fopen(fileName,"rt");
    fseek(fp,0,SEEK_END);
    int size = ftell(fp);
    fseek(fp,0,SEEK_SET);
    char* buf = new char[size];
    fread(buf,size,1,fp);
    fclose(fp);
    for (int i=0,j; i<size; i=j+1)
    {
        for (j=i; j<size; j++)
        {
            if (WHITE_SPACE(buf[j]))
                break;
        }
        for (int n=0; n<numOfWords; n++)
        {
            int len = strlen(words[n]);
            if (len == j-i && !memcmp(buf+i,words[n],len))
                count++;
        }
    }
    delete[] buf;
    return count;
}

但请注意,我没有编辑也没有测试过(正如我上面说的那样,“我的脑子里面”)......

答案 6 :(得分:0)

看看String matching algorithms

您还可以在github

中找到Boyer-Moore的实现示例

答案 7 :(得分:0)

该行

  

if((fgets(ch,3,fp))==“the”||(fgets(ch,3,fp))==“和”)

有几个问题:

  • 您无法将字符串值与==运算符进行比较;您需要使用strcmp库函数;
  • 您没有将同一输入与"the""and"进行比较;当第一次比较失败时,您将从输入中读取接下来的3个字符;

如果你抽象出输入和比较操作,生活会更容易;在高层次上,它看起来像这样:

#define MAX_WORD_LENGTH 10 // or however big it needs to be
...
char word[MAX_WORD_LENGTH + 1];
...
while ( getNextWord( word, sizeof word, fp )) // will loop until getNextWord 
{                                             // returns false (error or EOF)
  if ( match( word ) )
    count++;
}

getNextWord函数处理所有输入;它将从输入流中读取字符,直到它识别出一个“字”或直到输入缓冲区中没有剩余空间。在这种特殊情况下,我们假设“单词”只是任何非空白字符序列(意味着标点符号将被视为单词的一部分)。如果你想能够识别标点符号,这会变得有点困难;例如,'可能引用字符('hello'),在这种情况下它不应该是单词的一部分,或者它可能是收缩的一部分或者是posessive(它是,Joe的),其中如果应该成为单词的一部分。

#include <ctype.h>
...
int getNextWord( char *target, size_t targetSize, FILE *fp )
{
  size_t i = 0;
  int c;

  /**
   * Read the next character from the input stream, skipping
   * over any leading whitespace.  We'll add each non-whitespace
   * character to the target buffer until we see trailing 
   * whitespace or EOF.
   */
  while ( (c = fgetc( fp )) != EOF && i < targetSize - 1 )
  {
    if ( isspace( c ) )
    {
      if ( i == 0 )
        continue;
      else
        break;
    }
    else
    {
      target[i++] = c;
    }
  }

  target[i] = 0;      // add 0 terminator to string
  return i > 0;       // if i == 0, then we did not successfully read a word
}

match函数只是将输入的单词与目标单词列表进行比较,如果看到匹配则返回“true”(1)。在这种情况下,我们创建一个带有终止NULL条目的目标字列表;我们只是沿着列表走,将每个元素与我们的输入进行比较。如果我们到达NULL条目,我们找不到匹配项。

#include <string.h>
...
int match( const char *word )
{
  const char *targets[] = {"and", "the", NULL};
  const char *t = targets;

  while ( t && strcmp( t, word ))
    t++;

  return t != NULL;  // evaluates to true if we match either "the" or "and"
}

请注意,此比较区分大小写; “这个”不会与“the”相提并论。如果您想要不区分大小写的比较,则必须复制输入字符串并将其全部转换为小写,并将该副本与目标进行比较:

#include <stdlib.h>
#Include <ctype.h>
#include <string.h>
...
int match( const char *word )
{
  const char *targets[] = {"and", "the", NULL};
  const char *t = targets;

  char *wcopy = malloc( strlen( word ) + 1 );
  if ( wcopy )
  {
    char *w = word;
    char *c = wcopy;

    while ( *w )
      *c++ = tolower( *w++ );
  }
  else
  {
    fprintf( stderr, "malloc failure in match: fatal error, exiting\n" );
    exit(0);
  }

  while ( t && strcmp( t, wcopy))
    t++;

  free( wcopy );
  return t != NULL;  // evaluates to true if we match either "the" or "and"
}