Help writing a program (crossword puzzle)

In summary, the task is to create a program in C that takes user input to create a 2d array of a specified length and height. The inputs should only be letters 'a' to 'z', 'A' to 'Z', and '*' and any other input should cause the program to immediately exit. This array represents a crossword puzzle with '*' representing blanks between words. The program should print the array in a matrix form and find the row or column with the most appearances of '*'. There seems to be an issue with reading inputs, possibly due to the use of scanf("%c") which reads one character at a time and includes blank characters. Adding a space before the %c or manually testing for newline characters may help with this
  • #1
doktorwho
181
6

Homework Statement


I am supposed to write a program in C that does the following:
It creates a 2d array from your specifications and as inputs takes only letters 'a' to 'z', 'A' to 'Z' and '*' and nothing else. It should immediately exit if something else is inputed. This array represents a crossword puzzle that the user creates and the '*' represent the blanks that separate words. The program should print and array in a matrix form (nxm) where n and m are inputted numbers of array length and find a row or a coloumn with biggest number of '*" appearances.

Homework Equations


3. The Attempt at a Solution [/B]
C:
#include "stdio.h"
#define MAX_I 500
#define MAX_J 500

int main(void) {
  char words[MAX_I][MAX_J];
  int n, m, i, j;
 
  printf("Enter the length of your array: \n");
    scanf("%d", &n);
  printf("Enter the height of your array: \n");
    scanf(" %d", &m);
   
   printf("Enter the elements: \n");
   for(i = 0; i < n; i++)
   {
       for(j = 0; j < m; j++) {
          scanf("%c", &words[i][j]);
          if (((words[i][j] >= 'a' && words[i][j] <= 'z') || (words[i][j] >= 'A' && words[i][j] <= 'Z')) || (words[i][j] == '*'))
          {      //I am here checking if inputs are correct.
            continue;
          }
          else {
            printf("Invalid, program will exit now! \n");
            goto finish;
          }
      }
    }
   
    finish:
      return 0;
   
   printf("\n");
     for(i = 0; i < n; i++)
   {
       for(j = 0; j < m; j++) {
          printf("%c", words[i][j]);
       }
      printf("\n");   //This is used so that it gets printed in matrix form.
    }
   
}
This is just a starting point and its already giving me trouble. It doesn't take inputs and i don't know why. Its like its taking something as an input before asked to do so. Can you spot the bugz?
 
Physics news on Phys.org
  • #2
scanf ("%c", ) will read one character at at time, including newline characters, spaces, tabs etc. once you read one of these, your program will stop.
If you put a space in front of the %c in scanf, it will skip al blank charaters (newline, space, tab).
You can also test for newline characters yourself, and go to the next row if you read one.
 
  • #3
doktorwho said:

Homework Statement


I am supposed to write a program in C that does the following:
It creates a 2d array from your specifications and as inputs takes only letters 'a' to 'z', 'A' to 'Z' and '*' and nothing else. It should immediately exit if something else is inputed. This array represents a crossword puzzle that the user creates and the '*' represent the blanks that separate words. The program should print and array in a matrix form (nxm) where n and m are inputted numbers of array length and find a row or a coloumn with biggest number of '*" appearances.

Homework Equations


3. The Attempt at a Solution [/B]
C:
#include "stdio.h"
#define MAX_I 500
#define MAX_J 500

int main(void) {
  char words[MAX_I][MAX_J];
  int n, m, i, j;
 
  printf("Enter the length of your array: \n");
    scanf("%d", &n);
  printf("Enter the height of your array: \n");
    scanf(" %d", &m);
  
   printf("Enter the elements: \n");
   for(i = 0; i < n; i++)
   {
       for(j = 0; j < m; j++) {
          scanf("%c", &words[i][j]);
          if (((words[i][j] >= 'a' && words[i][j] <= 'z') || (words[i][j] >= 'A' && words[i][j] <= 'Z')) || (words[i][j] == '*'))
          {      //I am here checking if inputs are correct.
            continue;
          }
          else {
            printf("Invalid, program will exit now! \n");
            goto finish;
          }
      }
    }
  
    finish:
      return 0;
  
   printf("\n");
     for(i = 0; i < n; i++)
   {
       for(j = 0; j < m; j++) {
          printf("%c", words[i][j]);
       }
      printf("\n");   //This is used so that it gets printed in matrix form.
    }
  
}
This is just a starting point and its already giving me trouble. It doesn't take inputs and i don't know why. Its like its taking something as an input before asked to do so. Can you spot the bugz?
Your description of what is happening isn't very helpful ("doesn't take inputs"). I'm going to guess that you can input the array sizes OK (first two inputs), but things go wrong thereafter.

If so, your call to scanf() is at fault. The reason is due to the previous call to scanf(), for the array height. If you type 32 for the array height, you also press the Enter key. This key generates the newline character, but that isn't part of an integer, so it stays in the input buffer. The following call to scanf() picks it up.

One fix is to flush the input buffer, which you can do this way: fflush(stdin);
 
  • #4
willem2 said:
scanf ("%c", ) will read one character at at time, including newline characters, spaces, tabs etc. once you read one of these, your program will stop.
If you put a space in front of the %c in scanf, it will skip al blank charaters (newline, space, tab).
You can also test for newline characters yourself, and go to the next row if you read one.

Mark44 said:
Your description of what is happening isn't very helpful ("doesn't take inputs"). I'm going to guess that you can input the array sizes OK (first two inputs), but things go wrong thereafter.

If so, your call to scanf() is at fault. The reason is due to the previous call to scanf(), for the array height. If you type 32 for the array height, you also press the Enter key. This key generates the newline character, but that isn't part of an integer, so it stays in the input buffer. The following call to scanf() picks it up.

One fix is to flush the input buffer, which you can do this way: fflush(stdin);
That helped a lot and i was able to succesfully write it to do what it is supposed to. I have one question though. Part of this homework says that after we write this program we need to make another one which is the same concept like this one but uses dynamic memory to store inputs and only one pointer. I am to check the succesfulness of the program after each memory allocation and deallocate at the end. This is the part which i do not know how to do and was wondering if you could direct me to some useful site or text that shows how this is implemented? I do not have time to read an entire book as its due Thursday so something concise and useful would be good.
 
  • #5
doktorwho said:
That helped a lot and i was able to succesfully write it to do what it is supposed to. I have one question though. Part of this homework says that after we write this program we need to make another one which is the same concept like this one but uses dynamic memory to store inputs and only one pointer. I am to check the succesfulness of the program after each memory allocation and deallocate at the end. This is the part which i do not know how to do and was wondering if you could direct me to some useful site or text that shows how this is implemented? I do not have time to read an entire book as its due Thursday so something concise and useful would be good.
Use malloc() to allocate a buffer that is large enough for your array. When you're done with the memory, use free() to deallocate the memory. Here's a brief description of malloc() - http://www.cplusplus.com/reference/cstdlib/malloc/

I don't think you need an array that is 500 x 500 to store your words in. Probably 20 to 30 characters per word would be sufficient. If you have an array with 100 words, where each one is, say, 30 characters, that's 100 x 30 = 3000 bytes. Keep in mind that each "word" is a string, so you need to leave space at the end of the word for the null character.
 
  • #6
Mark44 said:
Use malloc() to allocate a buffer that is large enough for your array. When you're done with the memory, use free() to deallocate the memory. Here's a brief description of malloc() - http://www.cplusplus.com/reference/cstdlib/malloc/

I don't think you need an array that is 500 x 500 to store your words in. Probably 20 to 30 characters per word would be sufficient. If you have an array with 100 words, where each one is, say, 30 characters, that's 100 x 30 = 3000 bytes. Keep in mind that each "word" is a string, so you need to leave space at the end of the word for the null character.
Ok i will give this a read. How much does this change in my original problem solution? The parts that are included in the solutions are inputting of the characters and then going through the array to find the most * appearances over rows and coloumns. What will this modification change? Everything or certain parts?
 
  • #7
doktorwho said:
Ok i will give this a read. How much does this change in my original problem solution?
Your original program used a two-dimensional 500 x 500 array of char, of which your program used only a small portion. This array was allocated on the stack. Using malloc() you will be allocating the exact amount of memory you need for your 2D array, but the memory will be allocated on the heap.
doktorwho said:
The parts that are included in the solutions are inputting of the characters and then going through the array to find the most * appearances over rows and coloumns. What will this modification change? Everything or certain parts?
Here's some code I found on stackexchange (http://stackoverflow.com/questions/8740195/how-do-we-allocate-a-2-d-array-using-one-malloc-statement -- Ex. 3)that you can modify to suit your requirements.
C:
#define COLS ... // integer value > 0...
size_t rows;
int (*arr)[COLS]; ... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
   size_t i, j;
   for (i = 0; i < rows; i++)
      for (j = 0; j < COLS; j++)
         arr[i][j] = ...;
}
COLS is a constant that represents the maximum length of a word. It needs to include the null character.
Above, arr above is a pointer to an array, each element of which consists of COLS ints. In your program, change int in the declaration to char. In the inner for loop you can use scanf() to input to an individual character, but I would recommend not doing that. Instead, use scanf() to input the entire string.
 
  • #8
Mark44 said:
Your original program used a two-dimensional 500 x 500 array of char, of which your program used only a small portion. This array was allocated on the stack. Using malloc() you will be allocating the exact amount of memory you need for your 2D array, but the memory will be allocated on the heap.

Here's some code I found on stackexchange (http://stackoverflow.com/questions/8740195/how-do-we-allocate-a-2-d-array-using-one-malloc-statement -- Ex. 3)that you can modify to suit your requirements.
C:
#define COLS ... // integer value > 0...
size_t rows;
int (*arr)[COLS]; ... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
   size_t i, j;
   for (i = 0; i < rows; i++)
      for (j = 0; j < COLS; j++)
         arr[i][j] = ...;
}
COLS is a constant that represents the maximum length of a word. It needs to include the null character.
Above, arr above is a pointer to an array, each element of which consists of COLS ints. In your program, change int in the declaration to char. In the inner for loop you can use scanf() to input to an individual character, but I would recommend not doing that. Instead, use scanf() to input the entire string.
I have read the site you suggested and was able to write the modification succesfully. One last thing that bugs me is the part where it says:
Each time a memory is allocated during the process check the succesfulness of that function and if it was unsuccesfull report an error and close the program. How am i to do that?
 
  • #9
doktorwho said:
Each time a memory is allocated during the process check the succesfulness of that function and if it was unsuccesfull report an error and close the program. How am i to do that?
Use the value returned by malloc(). If this function succeeds in allocating a block of memory, it returns a pointer to the first byte of the memory block. If for some reason it isn't able to allocate the memory (due to no more memory being available, for example), it returns a null pointer.

Here's the same code as before, but this time with an else clause to report the error and exit. The argument to exit() is reported back to the OS. If you have several exit() calls, if you use different numbers for the argument to each, you can tell which part of your code failed.

C:
define COLS ... // integer value > 0...
size_t rows;
int (*arr)[COLS]; ... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
   size_t i, j;
   for (i = 0; i < rows; i++)
      for (j = 0; j < COLS; j++)
         arr[i][j] = ...;
}
else  // Wasn't able to allocate the memory requested
{
    printf("Memory allocation failed.");
    exit (1);
 
  • Like
Likes doktorwho
  • #10
Mark44 said:
Use the value returned by malloc(). If this function succeeds in allocating a block of memory, it returns a pointer to the first byte of the memory block. If for some reason it isn't able to allocate the memory (due to no more memory being available, for example), it returns a null pointer.

Here's the same code as before, but this time with an else clause to report the error and exit. The argument to exit() is reported back to the OS. If you have several exit() calls, if you use different numbers for the argument to each, you can tell which part of your code failed.

C:
define COLS ... // integer value > 0...
size_t rows;
int (*arr)[COLS]; ... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
   size_t i, j;
   for (i = 0; i < rows; i++)
      for (j = 0; j < COLS; j++)
         arr[i][j] = ...;
}
else  // Wasn't able to allocate the memory requested
{
    printf("Memory allocation failed.");
    exit (1);
I made it :D. Thanks!
 
Last edited:

1. What is the purpose of writing a program for a crossword puzzle?

The purpose of writing a program for a crossword puzzle is to automate the creation of a puzzle, making it easier and faster for creators to generate new puzzles. It can also help with tasks such as checking for duplicate words and ensuring symmetry in the puzzle.

2. What programming language should I use to write a crossword puzzle program?

There is no specific programming language that is best for writing a crossword puzzle program. It depends on your personal preferences and the features you want to include in your program. Some popular options include Python, Java, and C++.

3. Can I use an existing crossword puzzle program or do I need to create my own?

You can use an existing crossword puzzle program if you want to save time and effort. However, creating your own program can give you more control over the features and design of your puzzles.

4. What are the key features that should be included in a crossword puzzle program?

The key features of a crossword puzzle program may vary depending on your specific needs, but some common features include the ability to input clues and answers, generate a grid with black squares, check for duplicate words, and allow for editing and saving of puzzles.

5. Are there any resources or tutorials available to help with writing a crossword puzzle program?

Yes, there are many online resources and tutorials available that can help you learn how to write a crossword puzzle program. You can also find open-source codes of existing programs that you can use as a reference or starting point for your own program.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
21
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
893
  • Engineering and Comp Sci Homework Help
Replies
9
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
21
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
12
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
929
  • Engineering and Comp Sci Homework Help
Replies
4
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
8K
Back
Top