【问题标题】:Finding occurrences of specific word line by line from text file从文本文件中逐行查找特定单词的出现
【发布时间】:2015-05-23 03:51:17
【问题描述】:

我正在尝试逐行读出我的文本文件

FILE *infile;
char line[1000];
infile = fopen("file.txt","r");
while(fgets(line,1000,infile) != NULL) 
{
    //....
}
fclose(infile);

然后我需要找到一个特定的单词,例如“the”,并且需要查看它出现了多少次以及它还出现在了哪些行上。

我应该可以用这个数单词

int wordTimes = 0;
if((strcmp("the", currentWord) == 0)) 
{
    printf("'%s' appears in line %d  which is: \n%s\n\n", "the", line_num, line);
    wordTimes++;
}

其中line 是字符串所在的文本行,line_num 是字符串所在的行号。

然后单词显示的次数使用此代码:

if(wordTimes > 0)
{
    printf("'%s' appears %d times\n", "the", wordTimes);
}
else
{
    printf("'%s' does not appear\n", "the");
}

问题是我不确定如何将行中的每个单词与“the”进行比较,并且仍然打印出它适用的行。

为此我必须使用非常基本的 C,这意味着我不能使用 strtok()strstr()。我只能使用strlen()strcmp()

【问题讨论】:

  • 你能自己模拟strstr()和/或strtok()吗?您允许使用哪些功能 - strcmp() 似乎可以,但还有什么?
  • 你只需要多次调用它,每次从最后一场比赛之后开始,直到它没有找到任何东西。您还必须确保在找到任何内容之前和之后都有一个非 alpha 版本。
  • 你修改代码:char *here = line; while ((word = strstr(here, "the")) != NULL) { wordcount++; here = word + 1; } 除了你还需要检查单词是否被非字母字符包围。
  • 调用strstr()后,word指向三个连续字母the的开头,可能被空格包围,也可能不被空格包围,或者为空。
  • @DarkN3ss - 您必须在循环中调用它并每次将 return value of strstr + strlen("the") 作为输入传递,直到 strstr 返回 0。

标签: c find-occurrences


【解决方案1】:

也许你需要像这样写一个strword() 函数。我假设您可以使用<ctype.h> 中的分类函数(宏),但如果也不允许这样做,也有一些解决方法。

#include <assert.h>
#include <ctype.h>
#include <stdio.h>

char *strword(char *haystack, char *needle);

char *strword(char *haystack, char *needle)
{
    char *pos = haystack;
    char old_ch = ' ';
    while (*pos != '\0')
    {
        if (!isalpha(old_ch) && *pos == *needle)
        {
            char *txt = pos + 1;
            char *str = needle + 1;
            while (*txt == *str)
            {
                if (*str == '\0')
                    return pos;     // Exact match at end of haystack
                txt++, str++;
            }
            if (*str == '\0' && !isalpha(*txt))
                return pos;
        }
        old_ch = *pos++;
    }
    return 0;
}

int main(void)
{
    /*
    ** Note that 'the' appears in the haystack as a prefix to a word,
    ** wholly contained in a word, and at the end of a word - and is not
    ** counted in any of those places. And punctuation is OK.
    */
    char haystack[] =
        "the way to blithely count the occurrences (tithe)"
        " of 'the' in their line is the";
    char needle[] = "the";

    char *curpos = haystack;
    char *word;
    int count = 0;
    while ((word = strword(curpos, needle)) != 0)
    {
        count++;
        printf("Found <%s> at [%.20s]\n", needle, word);
        curpos = word + 1;
    }

    printf("Found %d occurrences of <%s> in [%s]\n", count, needle, haystack);

    assert(strword("the", "the") != 0);
    assert(strword("th", "the") == 0);
    assert(strword("t", "t") != 0);
    assert(strword("", "t") == 0);
    assert(strword("if t fi", "t") != 0);
    assert(strword("if t fi", "") == 0);
    return 0;
}

运行时,会产生:

Found <the> at [the way to blithely ]
Found <the> at [the occurrences (tit]
Found <the> at [the' in their line i]
Found <the> at [the]
Found 4 occurrences of <the> in [the way to blithely count the occurrences (tithe) of 'the' in their line is the]

有没有办法在没有&lt;ctype.h&gt; 的情况下执行strword 函数?

是的。我在开篇就说了这么多。由于使用的唯一函数/宏是isalpha(),因此您可以做出一些假设(您不在使用EBCDIC 的系统上),以便拉丁字母是连续的,您可以使用is_alpha() 代替@987654329 @ — 并从包含的标头列表中省略 &lt;ctype.h&gt;

static inline int is_alpha(int c)
{
    return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}

【讨论】:

  • 有没有办法在没有 ctype.h 的情况下执行 strword 函数?
  • 我不明白 is_alpha 调用的必要性?
  • @user93353:尝试没有它们的代码。然后它会在其他词的开头、中间或结尾愉快地拿起“the”。您不希望看到程序声称“other”是“the”这个词,对吗? (另外,要找到包含单词片段的单词,需要进行很多更改。但这是尝试回答不同问题的结果。)
  • @JonathanLeffler - 我明白了,但我没有意识到这就是你的目标 - 因为 strstr 没有这样做。我没有意识到 OP 想要这样做。
  • @user93353:这是一个字里行间的阅读问题,而不是真正在问题中明确说明。该问题反复提到“单词”,而不是“字符串”之类的东西。该问题仅负面提及strstr();它不能使用。在某种程度上,这个问题是可以解释的,但似乎我的解释并不太遥远。
猜你喜欢
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 2019-10-05
  • 2012-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多