微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从文件中读取特定单词?

如何解决如何从文件中读取特定单词?

我有一个文件,每行都包含单词及其同义词。 我正在编写这段代码,它应该逐行读取文件,然后从作为同义词的第二个单词开始显示它。 我在第一个循环中使用了变量 count 以便能够计算每个单词的同义词数量,因为同义词数量各不相同。此外,我使用了条件同义词[i]==',',因为每个同义词都用逗号分隔。 我编写这样的代码的目的是将它们放在二叉搜索树中以获得完整的字典。 该代码不包含任何错误,但它不起作用。 我已经尝试过每个循环,但也没有用。

来自文件的示例输入:

abruptly - dead,short,suddenly
acquittance - release
adder - common,vipera

示例预期输出

dead short suddenly
acquittance realse 
common vipera

代码如下:

void LoadFile(FILE *fp){
    int count; 
    int i;
    char synonyms[50]; 
    char word[50];
    while(fgets(synonyms,50,fp)!=NULL){
        for (i=0;i<strlen(synonyms);i++)
    if (synonyms[i]==',' || synonyms[i]=='\n')
        count++;
    }
    while(fscanf(fp,"%s",word)==1){
    for(i=1;i<strlen(synonyms);i++){
        ( fscanf(fp,synonyms)==1);
            printf("%s",synonyms);
        }
      }
    }
    int main(){
    char fn[]="C:/Users/CLICK ONCE/Desktop/Semester 4/i2206/Project/Synonyms.txt";
    FILE *fp;
    fp=fopen(fn,"rt");
    if (fp==NULL){
        printf("Cannot open this file");
    }
        else{
           LoadFile(fp);
        }
     return 0;
    }

解决方法

我认为代码中表现出的最大的概念误解是未能理解 fgetsfscanf 的工作原理。

考虑以下代码行:

while(fgets(synonyms,50,fp)!=NULL){
    ...
    while(fscanf(fp,"%49s",word)==1){
        for(i=1;i<strlen(synonyms);i++){
            fscanf(fp,synonyms);
            printf("%s",synonyms);
        }
    }
}

fgets 读取输入的一行。 (除非输入行的长度超过 49 个字符(48 + 换行符),在这种情况下 fgets 将只读取前 49 个字符。代码应该检查该条件并处理它。) next fscanf 然后从输入的 next 行读取一个单词。第一行实际上被丢弃了!如果输入的格式符合预期,第二个 scanf 会将单个 - 读入 synonyms。这使得 strlen(synonyms) 评估为 1,因此 for 循环终止。然后 while scanf 循环读取另一个单词,并且由于 synonyms 仍然包含长度为 1 的字符串,因此永远不会进入 for 循环。 while scanf 然后继续读取文件的其余部分。对 fgets 的下一次调用返回 NULL(因为 fscanf 循环已读取到文件末尾),因此 while/fgets 循环在 1 次迭代后终止。

我相信目的是让 scanfs 中的 while/fgetsfgets 读取的行进行操作。为此,应将所有 fscanf 调用替换为 sscanf

,

这是我的解决方案。为了便于阅读,我已将工作拆分为多个函数。实际的解析在 parse 函数中完成。该函数考虑了带连字符的复合词,例如 72。该词和他的同义词必须用连字符分隔,前面至少有一个空格。

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

// Trim leading and trailing space characters.
// Warning: string is modified
char* trim(char* s) {
    char* p = s;
    int l = strlen(p);

    while (isspace(p[l - 1])) p[--l] = 0;
    while (*p && isspace(*p)) ++p,--l;

    memmove(s,p,l + 1);
    return s;
} 

// Warning: string is modified
int parse(char* line)
{
    char* token;
    char* p;
    char* word;

    if (line == NULL) {
        printf("Missing input line\n");
        return 0;
    }

    // first find the word delimiter: an hyphen preceded by a space
    p = line;
    while (1) {
        p = strchr(p,'-');
        if (p == NULL) {
            printf("Missing hypen\n");
            return 0;
        }
        if ((p > line) && (p[-1] == ' ')) {
            // We found an hyphen preceded by a space
            *p = 0; // Replace by nul character (end of string)
            break;
        }
        p++; // Skip hyphen inside hypheneted word
    }
    word = trim(line);
    printf("%s ",word);

    // Next find synonyms delimited by a coma
    char delim[] = ",";
    token = strtok(p + 1,delim);
    while (token != NULL) {
        printf("%s ",token);
        token = strtok(NULL,delim);
    }
    printf("\n");
    return 1;
}

int LoadFile(FILE* fp)
{
    if (fp == NULL) {
        printf("File not open\n");
        return 0;
    }
    int ret = 1;
    char str[1024];  // Longest allowed line
    while (fgets(str,sizeof(str),fp) != NULL) {
        str[strcspn(str,"\r\n")] = 0; // Remove ending \n
        ret &= parse(str);
    }
    return ret;
}

int main(int argc,char *argv[])
{
    FILE* fp;
    char* fn = "Synonyms.txt";
    fp = fopen(fn,"rt");
    if (fp == NULL) {
        perror(fn);
        return 1;
    }
    int ret = LoadFile(fp);
    fclose(fp);
    return ret;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。