Почему мой оператор printf () в моей функции searchPuzzle не работает? - PullRequest
0 голосов
/ 26 апреля 2020

По какой-то причине мой оператор печати в моей функции searchPuzzle не работает. Ребята, вы можете объяснить причину? Я пытаюсь найти определенные слова в кроссворде размером 15х15. Слово, которое я пытаюсь найти, - это штаты с США, например, Нью-Йорк. Char ** arr представляет кроссворд. в то время как список char ** представляет список состояний. Моя go предназначена для моей функции - попытаться найти состояния в кроссворде и распечатать найденные состояния. Int listsize имеет значение 50. В то время как п имеет значение 15.

1002 * Это кроссворд головоломка: WDBMJQDB C JNQPTI IRZUXUZEAOIORTN MNZPLRNHLYLXHMD MYEKAIDPIULYOWI AOABARKUFVIHLAA LONMRXKIOJNAVRN AEPTAARARTOWAIA SU C ZAUSINAIALZV KOTAONRKISSIAON AHXSVKAIAEAIBNE UDSXNX C C DWGSAAV OISDWLEJNJTXMHA MOXWTNHQDXOQAQD RUUVGEORGIAQVDA VFLORIDALGLWOXN

Это список штатов: Алабама Аляска, штат Аризона, штат Арканзас, штат Калифорния, штат Коннектикут, штат Массачусетс, штат Массачусетс, штат Массачусетс. Нью-Гемпшир Нью-Джерси Нью-Мексико Нью-Йорк Северная Каролина Северная Дакота Огайо Оклахома Орегон Пенсильвания Род-Айленд Южная Каролина Южная Дакота Теннесси Техас Юта Вермонт Вирджиния Вашингтон Запад Вирджиния Висконсин Вайоминг

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


  }



}

Ответы [ 2 ]

0 голосов
/ 26 апреля 2020
           if( *(*(list + a) + k) == *(*(arr + c) + b) ){
              k++;
           }
           if( *(*(list + a) + k) != *(*(arr + c) + b) ){
              k = 0;
              break;
           }
  1. В первом if вы увеличиваете k, если найдете совпадение. Затем в следующем if мы проверяем следующий символ в слове (поскольку мы сделали k++) с тем же символом *(*(arr + c) + b) из кроссворда. Например, в NEWYORK вы сопоставляете N с N (пока что хорошо), затем сравниваете E с N, который не равен, так что он выходит из l oop. Вы должны использовать if .. else здесь вместо двух отдельных if s, поскольку второе условие следует проверять только в том случае, если первое ложно.

  2. Когда вы обнаружите не соответствующий символ, вы используете break. Это вырвется из c l oop, что означает, что, если какой-либо символ в строке кроссворда не соответствует слову из списка, оставшиеся символы в этой строке проверяться не будут. Здесь вам не нужно выходить из цикла; установка k = 0 должна быть достаточной.

  3. В *(*(arr + c) + b) вы увеличиваете c во внутреннем l oop, поэтому вы проверяете только вертикальные совпадения в кроссворде. Если вы также хотите проверить горизонтальные совпадения, вы должны также выполнить те же проверки после изменения порядка вложенности циклов b и c. (ИЛИ вы можете проверить *(*(arr + b) + c) (изменили b и c положение) в том же l oop и использовать другую переменную для горизонтали вместо k. Но обратите внимание, что это не работает, если кроссворд не квадратный ie. Not NxN)
  4. Как уже упоминалось в комментариях @bruno, используйте arr[c][b] вместо *(*(arr + c) + b), поскольку он более читабелен и удобен в обслуживании. Также используйте al oop для чтения символов в кроссворде. Это будет более удобным, чем %c %c %c ...

  5. На моей машине linux следующий код усекает один дополнительный символ из слов в списке. Скорее всего, потому что вы находитесь на Windows, а Windows использует \r\n окончания строк и Linux использует \n окончания. Так что это не будет работать так, как вы ожидаете, если ваш файл списка слов был написан на компьютере, отличном от windows (Ma c, Linux). Если вы хотите, чтобы он работал где угодно, вы можете использовать strcspn функцию с \r\n для удаления символов новой строки.

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

После внося изменения, вы должны получить следующее (скажите, если чего-то не хватает):

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

Поскольку это школьная работа, я позволю вам внести изменения в код.

0 голосов
/ 26 апреля 2020

Я немного изменил функцию печати. Я полагаю, это должно работать:

#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(X) sizeof(X) / sizeof(X[0])

void printPuzzle(const char ** arrP, int size){
  for (int i = 0; i < size; i++){
     printf(*arrP++);
     printf("\n");
  }
}


// Main function, DO NOT MODIFY!!!   
int main(int argc, char **argv) {
 const char * puzzle [] = {"ABC","DEF","GHI"};
printPuzzle(puzzle, ARRAY_SIZE(puzzle));
  return 0;
}
...