检查字符串中是否包含所有字符值

4
我目前正在处理这个任务,但卡住了。目标是读取一个文件并查找这些字符值是否存在于文件中的字符串中。我必须将来自文件的字符串与作为参数输入的另一个字符串进行比较。然而,只要文件中的每个字符值都在字符串中,它就会“匹配”。
例如(输入和输出):
./a.out file1 done done is in bonehead done is not in doggie 例如(file1):
bonehead doggie 如您所见,比较字符串的顺序并不重要,并且文件也遵循每行一个单词的格式。我已经编写了一个程序,可以找到另一个字符串中是否存在字符值,但这只是问题的一部分。有什么想法可以解决这个问题吗?
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv){
    FILE *f = fopen(argv[1], "r");
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    char *word = argv[2];

    if(argc != 3){
            printf("./a.out <file> <word>\n");
            exit(EXIT_SUCCESS);
    }

    if(f == NULL){
            printf("file empty\n");
            exit(EXIT_SUCCESS);
    }

    // confused what this loop does too
    while((read = getline(&line, &len, f)) != -1){
            char *c = line;
            while(*c){
                    if(strchr(word, *c))
                            printf("can't spell \"%s\" without \"%s\"!\n", line, word);
                    else
                            printf("no \"%s\" in \"%s\".\n", word, line);
            c++;
            }
    }
    fclose(f);
    exit(EXIT_SUCCESS);
}

只是有点混乱。在这里,您正在测试文件中单词的字符是否在输入中。 - Julien Lopez
2
只需设置一个名为 all_found 的变量,其值为真。如果 strchr 返回 NULL,则将 all_found 设置为假,并退出循环。 - Antti Haapala -- Слава Україні
@Joe 我相信是这样的。你正在迭代文件中单词的字符,并使用 strchr 检查该字符是否在你的输入 word 中。难道你不应该做相反的操作吗? - Julien Lopez
1
е•ҠпјҢдҪ еә”иҜҘдҪҝз”Ёchar *c = word;е’Ңstrchr(line, *c)пјӣдҪ жӯЈеңЁжЈҖжҹҘе‘Ҫд»ӨиЎҢдёӯеҚ•иҜҚзҡ„жүҖжңүеӯ—з¬ҰжҳҜеҗҰеӯҳеңЁдәҺз»ҷе®ҡзҡ„иЎҢдёӯгҖӮ - Antti Haapala -- Слава Україні
是的,在 while (*c) {...} 循环之外。 - Antti Haapala -- Слава Україні
显示剩余12条评论
2个回答

0

不确定这个循环是做什么的
while (read ... 这一行显然从文件中读取行,并将它们放入 line 变量中。

*c 是指向变量 line 开始位置的指针,这个指针通过 c++ 递增,以便访问文件中单词中的每个字母。当 *c 指向空终止符(0)时,while 循环将被终止。

if (strchr(word ... 行测试测试单词是否包含来自文件中单词的一个字母。 这似乎与您尝试做的相反 - 查找测试单词中的所有字母是否都可以在文件中的单词中找到。

printf 行不合理,因为没有二选一 - 您需要一行打印“是”,表示我们的字母存在,一行打印“否”,表示至少有一个字母不存在。

printf语句应该放在比较循环外面,这样你就不会为每个单词获得多行输出。添加一个标志以显示单词中是否存在任何字母。在开始时将标志设置为1,并仅在字母不存在时将其更改为0,然后使用标志来打印两种结果语句之一。
这段代码可能有所帮助。
    /* set flag to 'letters all present' */
    int flag = 1;
    /* set pointer c to start of input line */
    c = word;
    /* test word from file for each letter in test word */
    while(*c) {
        if(strchr(line, *c) == NULL) {
            /* set flag to letter not present */
            flag = 0;
            break;
        }
        c++;
    }

0
另一种方法是简单地保留每个从文件中读取的行中匹配的字符的sum,对于测试提供的每个唯一字符添加一个,并且如果总和等于由唯一字符组成的字符串的长度,则搜索项,则来自文件中读取的行包含搜索项中的每个唯一字符。
#include <stdio.h>
#include <string.h>

#define MAXC 256

int main (int argc, char **argv) {

    if (argc < 3 ) {    /* validate required arguments */
        fprintf (stderr, "error: insufficient input, usage: %s file string\n",
                argv[0]);
        return 1;
    }

    FILE *fp = fopen (argv[1], "r");
    char line[MAXC] = "";
    char *s = argv[2];  /* string holding search string */
    size_t slen = strlen(s), sum = 0, ulen;
    char uniq[slen+1];  /* unique characters in s */

    if (!fp) {  /* validate file open */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    memset (uniq, 0, slen+1);  /* zero the VLA */
    /* fill uniq with unique characters from s */
    for (; *s; s++) if (!strchr (uniq, *s)) uniq[sum++] = *s;
    ulen = strlen (uniq);
    s = argv[2];    /* reset s */

    while (fgets (line, MAXC, fp)) {    /* for each line in file */
        if (strlen (line) - 1 < ulen) { /* short line, continue  */
            printf ("%s is not in %s", s, line);
            continue;
        }
        char *up = uniq;    /* ptr to uniq */
        sum = 0;            /* reset sum   */
        while (*up) if (strchr (line, *up++)) sum++; /* count chars */
        if (sum < ulen) /* validate sum */
            printf ("%s is not in %s", s, line);
        else
            printf ("%s is in %s", s, line);
    }
    fclose (fp); /* close file */

    return 0;
}

示例使用/输出

$ ./bin/strallcinc dat/words.txt done
done is in bonehead
done is not in doggie

对于搜索字符串中的重复字符同样适用。例如:

$ ./bin/strallcinc dat/words.txt doneddd
doneddd is in bonehead
doneddd is not in doggie

你可以决定是否以不同的方式处理重复字符,但你应该确定如何应对这种情况。

如果你有任何问题,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接