-1

I have a code called unscramble that takes two files, Jumbled.txt and dictionary.txt and finds if any words contain the same characters in both the files or not, for instance, here is a sample input for

Jumbled.txt:                                  
Hello
Wassup
Rigga
Boyka
Popeye

dictionary.txt:
olleH
Yello
elloH
lloeH
aggiR
ggiRa
giRag
yokaB
Bakoy
kaBoy
eyePop
poePye

and the expected output of the code above is:

Hello: olleH elloH lloeH
Wassup: NO MATCHES
Rigga: aggiR ggiRa giRag
Boyka: yokaB Bakoy kaBoy
Popeye: eyePop poePye

Here is my code that attempts to solve it:

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

#define MAX_WORD_LEN 50
#define MAX_DICT_WORDS 500000
#define MAX_JUMBLES 10000

char dict[MAX_DICT_WORDS][MAX_WORD_LEN + 1];
int dict_size;

char jumbles[MAX_JUMBLES][MAX_WORD_LEN + 1];
int jumbles_size;

int compare_chars(const void *a, const void *b) {
    return *(char *)a - *(char *)b;
}

void sort_chars(char *s) {
    qsort(s, strlen(s), sizeof(char), compare_chars);
}

int compare_words(const void *a, const void *b) {
    return strcmp((char *)a, (char *)b);
}

void load_dict(const char *filename) {
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        perror("Error opening dictionary file");
        exit(1);
    }
    dict_size = 0;
    char word[MAX_WORD_LEN + 1];
    while (fgets(word, MAX_WORD_LEN + 1, fp) != NULL) {
        int len = strlen(word);
        if (len > 0 && word[len - 1] == '\n') {
            word[len - 1] = '\0';  // remove newline
        }
        if (len > 1 && len <= MAX_WORD_LEN) {
            strcpy(dict[dict_size++], word);
        }
    }
    fclose(fp);
    qsort(dict, dict_size, sizeof(dict[0]), compare_words);
}

void load_jumbles(const char *filename) {
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        perror("Error opening jumbles file");
        exit(1);
    }
    jumbles_size = 0;
    char word[MAX_WORD_LEN + 1];
    while (fgets(word, MAX_WORD_LEN + 1, fp) != NULL) {
        int len = strlen(word);
        if (len > 0 && word[len - 1] == '\n') {
            word[len - 1] = '\0';  // remove newline
        }
        if (len > 1 && len <= MAX_WORD_LEN) {
            strcpy(jumbles[jumbles_size++], word);
        }
    }
    fclose(fp);
}

void unscramble() {
    char sorted[MAX_WORD_LEN + 1];
    for (int i = 0; i < jumbles_size; i++) {
        strcpy(sorted, jumbles[i]);
        sort_chars(sorted);
        printf("%s: ", jumbles[i]);
        int count = 0;
        for (int j = 0; j < dict_size && count < 10; j++) {
            if (strcmp(sorted, dict[j]) == 0) {
                printf("%s ", dict[j]);
                count++;
            }
        }
        if (count == 0) {
            printf("NO MATCHES");
        }
        printf("\n");
    }
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s <dictionary> <jumbles>\n", argv[0]);
        return 1;
    }
    load_dict(argv[1]);
    load_jumbles(argv[2]);
    unscramble();
    return 0;
}

However, when I do ./unscramble dictionary.txt Jumbled.txt, this is what I get:

xxxxxxxxx@LAPTOPxxxxxxxx:~$ ./unscramble dictionary.txt Jumbled.txt
 lloeHH
: NO MATCHES
 giRagR
 kaBoyB
 poePyep

I've been trying to debug this and change up my code but nothing is working, what is the problem here?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Deezel
  • 111
  • 6
  • Where's the call to "sort the characters" of the dictionary entries when comparing??? (PS: German has about 8x as many words as English. German dictionaries list about 150,000 words... Your 500,000 must be in anticipation of some unknown language...) – Fe2O3 Feb 19 '23 at 09:01
  • Your program doesn't produce the output you give when I run it – Paul Hankin Feb 19 '23 at 09:09
  • @Fe2O3 its only english but thats what I'm told at least to have at maximum 500,000 – Deezel Feb 19 '23 at 09:10
  • @PaulHankin can you let me know what output do u get? – Deezel Feb 19 '23 at 09:11
  • Did you not ask the same question an hour or so ago? – Harith Feb 19 '23 at 09:15
  • @Haris that was for compilation only, not for the output – Deezel Feb 19 '23 at 09:23
  • I had posted the required change to make this code work as you want. Your ability to adjust your own code seems to me to rely heavily on the guidance of others. I wish you well going forward. – Fe2O3 Feb 19 '23 at 10:11
  • What is the length of file `Jumbled.txt`? – chux - Reinstate Monica Feb 19 '23 at 16:06
  • Have you tried running your code line-by-line in a debugger while monitoring the control flow and the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Feb 19 '23 at 17:00

1 Answers1

1

At least these errors:

Enable all compiler warnings

Fix all warnings.

Sorted dictionary

The dictionary set of words are sorted. If original file order expected, do not sort the dictionary.

// Do not expect
Hello: olleH elloH lloeH
// Expect
Hello: elloH lloeH olleH

Given OP's expected output, there is no need to sort the words

Unsorted words

Code relies on each individual word's letter are sorted, yet individual letters in the dictionary words are not sorted. Form a sorted string before passing to strcmp(sorted, dict[j]).

Code should not sort letters or words more than once

Do it once and save results.

Advanced: Sorting amiss when a char value is negative.

String should be sorted as unsigned char. That is what strcmp() does.

// return *(char*) a - *(char*) b;
return *(unsigned char*) a - *(unsigned char*) b;

Following test code suggested

FILE *outf = fopen("Jumbled.txt", "w");
fputs("Hello\n", outf);
fputs("Wassup\n", outf);
fputs("Rigga\n", outf);
fputs("Boyka\n", outf);
fputs("Popeye\n", outf);
fclose(outf);

outf = fopen("dictionary.txt", "w");
fputs("olleH\n", outf);
fputs("Yello\n", outf);
fputs("elloH\n", outf);
fputs("lloeH\n", outf);
fputs("aggiR\n", outf);
fputs("ggiRa\n", outf);
fputs("giRag\n", outf);
fputs("yokaB\n", outf);
fputs("Bakoy\n", outf);
fputs("kaBoy\n", outf);
fputs("eyePop\n", outf);
fputs("poePye\n", outf);
fclose(outf);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256