Help writing a program (crossword puzzle)

  • #1
179
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 doesnt take inputs and i dont know why. Its like its taking something as an input before asked to do so. Can you spot the bugz?
 

Answers and Replies

  • #2
1,956
252
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
33,714
5,412

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 doesnt take inputs and i dont 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
179
6
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.
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
33,714
5,412
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
179
6
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
33,714
5,412
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
179
6
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
33,714
5,412
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
179
6
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:

Related Threads on Help writing a program (crossword puzzle)

  • Last Post
Replies
2
Views
757
  • Last Post
Replies
7
Views
1K
  • Last Post
Replies
3
Views
2K
Replies
3
Views
980
Replies
18
Views
8K
Replies
15
Views
3K
Replies
1
Views
703
Replies
3
Views
627
Replies
0
Views
2K
Top