为什么我的 searchPuzzle 函数中的 printf() 语句不起作用?

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

出于某种原因,我的 searchPuzzle 函数中的 print 语句不起作用。大佬能解释下原因吗?我试图在 15x15 的填字游戏中找到某些单词。我要查找的词是美国的州,例如纽约。 char ** arr 代表填字游戏。而 char** 列表代表状态列表。我的目标是我的功能是尝试在填字游戏中找到状态并打印出它确实找到的状态。 int listsize 的值为 50。而 n 的值为 15。

这是填字游戏: 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 MY 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 ART O W A I A S U C Z A U S I N A I A L Z V KO T A O N R K I 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

这是州列表: 阿拉巴马州 阿拉斯加州 亚利桑那 阿肯色州 加州 科罗拉多州 康涅狄格州 特拉华州 佛罗里达 乔治亚州 夏威夷 爱达荷州 伊利诺伊州 印第安纳州 爱荷华州 堪萨斯州 肯塔基州 路易斯安那州 缅因州 马里兰州 马萨诸塞州 密歇根州 明尼苏达州 密西西比州 密苏里州 蒙大拿 内布拉斯加州 内华达州 新罕布什尔 新泽西州 新墨西哥 纽约 北卡罗来纳 北达科他州 俄亥俄州 俄克拉何马州 俄勒冈州 宾夕法尼亚州 罗德岛 南卡罗来纳 南达科他州 田纳西州 得克萨斯州 犹他州 佛蒙特 弗吉尼亚州 华盛顿 西弗吉尼亚 威斯康星州 怀俄明州

#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) = '[=10=]';   
  }

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


  }



}

我稍微修改了打印功能。我想它应该可以工作:

#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;
}
           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 中,您将 NN 进行匹配(到目前为止一切正常),然后将 EN 进行比较,后者不相等,因此会中断跳出循环。您应该在此处使用 if .. else,而不是两个单独的 if,因为仅当第一个条件为假时才应检查第二个条件。

  2. 当您找到不匹配的字符时,您正在使用 break。这将跳出 c 循环,这意味着,如果填字游戏行中的任何字符与列表中的单词不匹配,则不会检查该行中的其余字符。在这里,您不必跳出循环;设置 k = 0 应该足够了。

  3. *(*(arr + c) + b) 中,您在内循环中递增 c,因此您只检查纵横字谜中的垂直匹配。如果你还想检查水平匹配,你也应该在改变 bc 循环的嵌套顺序后做同样的检查。 (或者您可以在同一循环中检查 *(*(arr + b) + c)(更改了 b 和 c 位置)并使用另一个水平变量代替 k。但请注意,如果填字游戏不是正方形,即这不起作用。不是 NxN)
  4. 正如@bruno 在评论中提到的,使用 arr[c][b] 而不是 *(*(arr + c) + b) 因为它更具可读性和可维护性。还可以使用循环来读取填字游戏中的字符。这将比 %c %c %c ...

  5. 更易于维护
  6. 在我的 linux 机器中,以下代码从列表中的单词中截断了一个额外的字符。很可能是因为您在 Windows 上,并且 Windows 使用 \r\n 行尾,而 Linux 使用 \n 行尾。因此,如果您的单词列表文件是在非 windows 机器(Mac、Linux)中编写的,这将不会像您预期的那样工作。如果你想让它在任何地方工作,你可以使用 use 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) = '[=11=]';   
  }

进行更改后,您应该得到这个(告诉是否缺少任何内容):

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

既然是学校作业,我会让你修改代码。