Check if all char values are present in string

2019-06-24 07:48发布

I'm currently working on this assignment and I'm stuck. The objective is to read a file and find if these char values exist in the String from the file. I have to compare a String from a file to another String I put in as an argument. However, just as long as each char value is in the String from the file then it "matches".

Example (input and output):

./a.out file1 done
done is in bonehead
done is not in doggie

Example (file1):

bonehead
doggie

As you can see the order in which is compares Strings does not matter and the file also follows one word per line. I've put together a program that finds if the char value is present in the other String but that is only part of the problem. Any idea how to go about this?

#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);
}

2条回答
来,给爷笑一个
2楼-- · 2019-06-24 08:03

Another approach would simply keep a sum of each character matched in the line read from the file, adding one for each unique character in the word supplied to test, and if the sum is equal to the length of the string made up by the unique characters is the search term, then each of the unique characters in the search term are included in the line read from the file.

#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;
}

Example Use/Output

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

which would work equally well for duplicate characters in the search string. e.g.

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

You can decide if you would handle duplicate characters differently, but you should make some determination on how that contingency will be addressed.

Let me know if you have any questions.

查看更多
Explosion°爆炸
3楼-- · 2019-06-24 08:25

confused what this loop does
The while (read ... line obviously reads in lines from your file, placing them in the line variable

*c is a pointer to the start of the variable line and this pointer is incremented by c++, so that each letter in the word from the file is accessed. The while loop will be terminated when *c points to the null terminator (0).

The if (strchr(word ... line is testing if the test word contains one of the letters from the word in the file. This seems to be the reverse of what you are trying to do - finding if all the letters in the test word can be found in the word from the file.

The printf lines are not sensible because there is no either/or - you need one line to print 'yes' our letters are present and one line to print 'no' at least one letter is not present.

The printf statements should be outside the comparison loop, so that you don't get multiple lines of output for each word. Add a flag to show if any letter does not exist in the word. Set flag to 1 at start, and only change it to 0 when a letter is not present, then use the flag to print one of the two outcome statements.

This code snippet may help

    /* 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++;
    }
查看更多
登录 后发表回答