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;
}
}
}
}
}
In the first
if, you incrementkif you find a match. Then, in the nextif, we are checking the next character in the word (since we didk++), with the same character*(*(arr + c) + b)from the crossword. For example, inNEWYORK, you matchNwithN(so far good), then compareEwithNwhich is not equal, so it breaks out of loop. You should use anif .. elsehere, instead of two separateifs, since the second condition should only be checked if the first is false.When you find a non-matching character, you are using
break. This will break out of thecloop, 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; settingk = 0should be enough.*(*(arr + c) + b)you are incrementingcin 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 ofbandcloops. (OR you can check*(*(arr + b) + c)(changed b and c position) in the same loop and use another variable for horizontal in place ofk. But note that this does not work if crossword is not square ie. not NxN)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 ...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\nline endings and Linux uses\nendings. 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 usestrcspnfunction with\r\nto remove new line characters.After making changes, you should get this (tell if anything is missing):
Since it is a school work, I will let you make the changes in code.