Search code examples
ccrossword

Why isn't my printf() statement in my searchPuzzle function isn't working?


For some reason, my print statement within my searchPuzzle function isn't working. Can you guys explain the reason why? I am trying to find certain words within a crossword puzzle which is 15x15. The word I am trying to find is the states with the US, like NewYork for example. The char ** arr represents the crossword puzzle. while the char** list represents the list of states. My go is for my function is to try to find the states in the crossword puzzle and to print out the states it does find. Int listsize has the value of 50. While n has the value of 15.

This is the cross word puzzle: W D B M J Q D B C J N Q P T I I R Z U X U Z E A O I O R T N M N Z P L R N H L Y L X H M D M Y E K A I D P I U L Y O W I A O A B A R K U F V I H L A A L O N M R X K I O J N A V R N A E P T A A R A R T O W A I A S U C Z A U S I N A I A L Z V K O T A O N R K I S S I A O N A H X S V K A I A E A I B N E U D S X N X C C D W G S A A V O I S D W L E J N J T X M H A M O X W T N H Q D X O Q A Q D R U U V G E O R G I A Q V D A V F L O R I D A L G L W O X N

This is the list of states: Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois Indiana Iowa Kansas Kentucky Louisiana Maine Maryland Massachusetts Michigan Minnesota Mississippi Missouri Montana Nebraska Nevada NewHampshire NewJersey NewMexico NewYork NorthCarolina NorthDakota Ohio Oklahoma Oregon Pennsylvania RhodeIsland SouthCarolina SouthDakota Tennessee Texas Utah Vermont Virginia Washington WestVirginia Wisconsin Wyoming

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// DO NOT INCLUDE OTHER LIBRARY!

// Declarations of the two functions you will implement
// Feel free to declare any helper functions
void printPuzzle(char** arr, int n);
void searchPuzzle(char** arr, int n, char** list, int listSize);

// Main function, DO NOT MODIFY!!!  
int main(int argc, char **argv) {
  int bSize = 15;
  if (argc != 2) {
     fprintf(stderr, "Usage: %s <puzzle file name>\n", argv[0]);
     return 2;
  }
  int i, j;
  FILE *fptr;
  char **block = (char**)malloc(bSize * sizeof(char*));
  char **words = (char**)malloc(50 * sizeof(char*));

  // Open file for reading puzzle
  fptr = fopen(argv[1], "r");
  if (fptr == NULL) {
     printf("Cannot Open Puzzle File!\n");
     return 0;
  }

  // Read puzzle block into 2D arrays
  for(i=0; i<bSize; i++){
     *(block+i) = (char*)malloc(bSize * sizeof(char));

     fscanf(fptr, "%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", *(block+i), *(block+i)+1, *(block+i)+2, *(block+i)+3, *(block+i)+4, *(block+i)+5, *(block+i)+6, *(block+i)+7, *(block+i)+8, *(block+i)+9, *(block+i)+10, *(block+i)+11, *(block+i)+12, *(block+i)+13, *(block+i)+14 );
  }
  fclose(fptr);

  // Open file for reading word list
  fptr = fopen("states.txt", "r");
  if (fptr == NULL) {
     printf("Cannot Open Words File!\n");
     return 0;
  }

  // Save words into arrays
  for(i=0; i<50; i++){
     *(words+i) = (char*)malloc(20 * sizeof(char));
     fgets(*(words+i), 20, fptr);       
  }

  // Remove newline characters from each word (except for the last word)
  for(i=0; i<49; i++){
     *(*(words+i) + strlen(*(words+i))-2) = '\0';   
  }

  // Print out word list
  printf("Printing list of words:\n");
  for(i=0; i<50; i++){
     printf("%s\n", *(words + i));      
  }
  printf("\n");

  // Print out original puzzle grid
  printf("Printing puzzle before search:\n");
  printPuzzle(block, bSize);
  printf("\n");

  // Call searchPuzzle to find all words in the puzzle
  searchPuzzle(block, bSize, words, 50);
  printf("\n");

  // Print out final puzzle grid with found words in lower case
  printf("Printing puzzle after search:\n");
  printPuzzle(block, bSize);
  printf("\n");

  return 0;
}











void printPuzzle(char** arr, int n){
  // This function will print out the complete puzzle grid (arr). It must produce the output in the SAME format as the samples in the instructions.
  // Your implementation here 

  for (int i = 0; i < n; i++){
     for (int j = 0; j < n; j++){
           printf("%c ", *(*(arr + i) + j));
     }

     printf("\n");
  }



}














void searchPuzzle(char** arr, int n, char** list, int listSize){
  // This function checks if arr contains words from list. If a word appears in arr, it will print out that word and then convert that word entry in arr into lower case.
  // Your implementation here



for(int e = 0; e < listSize; e++){ 
     for(int f = 0; f < strlen(*(list+e)); f++){
        if(*(*(list + e) + f) >= 'a' &&  *(*(list + e) + f) <= 'z' ){
           *(*(list + e) + f) = *(*(list + e) + f) - ('a' - 'A');
           }
     }
  }











  int k = 0;
  for(int a = 0; a < listSize; a++){
     for(int b = 0; b < n; b++){
        for(int c = 0; c < n; c++){

              if(*(*(list + a) + k) >= 'a' &&  *(*(list + a) + k) <= 'z' ){
                 *(*(list + a) + k) = *(*(list + a) + k) - ('a' - 'A');
              }

           if( *(*(list + a) + k) == *(*(arr + c) + b) ){
              k++;
           }
           if( *(*(list + a) + k) != *(*(arr + c) + b) ){
              k = 0;
              break;
              }
           printf("%i ", k);
           if ( k == (strlen(*(list+a))-1) ){
                 printf("Found: ");
                 for(int l = 0; l < strlen(*(list+a)); l++){
                    printf("%c", *(*(list + a) + l));
                    //printf("\n");
                 }
                 printf("\n");
                 k = 0;
                 break;
           }
        }
     }


  }



}

Solution

  •            if( *(*(list + a) + k) == *(*(arr + c) + b) ){
                  k++;
               }
               if( *(*(list + a) + k) != *(*(arr + c) + b) ){
                  k = 0;
                  break;
               }
    
    1. In the first if, you increment k if you find a match. Then, in the next if, we are checking the next character in the word (since we did k++), with the same character *(*(arr + c) + b) from the crossword. For example, in NEWYORK, you match N with N (so far good), then compare E with N which is not equal, so it breaks out of loop. You should use an if .. else here, instead of two separate ifs, since the second condition should only be checked if the first is false.

    2. When you find a non-matching character, you are using break. This will break out of the c loop, meaning that, if any character in a crossword line fails to match the word from list, the remaining characters in that line will not be checked. Here, you don't have to break out of the loop; setting k = 0 should be enough.

    3. In *(*(arr + c) + b) you are incrementing c in the inner loop, so you are only checking for vertical matches in the crossword. If you want to check for horizontal matches also, you should also do the same checks after changing the nesting order of b and c loops. (OR you can check *(*(arr + b) + c)(changed b and c position) in the same loop and use another variable for horizontal in place of k. But note that this does not work if crossword is not square ie. not NxN)
    4. As @bruno mentioned in comments, use arr[c][b] instead of *(*(arr + c) + b) as it is more readable and maintainable. Also use a loop to read characters in the crossword. That will be more maintainable than %c %c %c ...

    5. In my linux machine, the following code is truncating one extra character from the words in list. Most likely because you are on Windows, and Windows uses \r\n line endings and Linux uses \n endings. So this won't work as you expect if your word list file was written in non-windows machine (Mac, Linux). If you want it to work anywhere, you can use strcspn function with \r\n to remove new line characters.

      // Remove newline characters from each word (except for the last word)
      for(i=0; i<49; i++){
         *(*(words+i) + strlen(*(words+i))-2) = '\0';   
      }
    

    After making changes, you should get this (tell if anything is missing):

    Found:ALABAMA
    Found:ALASKA
    Found:ARIZONA
    Found:CALIFORNIA
    Found:FLORIDA
    Found:GEORGIA
    Found:HAWAII
    Found:ILLINOIS
    Found:INDIANA
    Found:NEVADA
    

    Since it is a school work, I will let you make the changes in code.