Search code examples
arrayscstructure

Accessing the last element on a row in a 2D array that is in a structure


I'm attempting to access the last element on each row of a 2D array that is inside a structure. I'm, attempting to determine if a specific character is in that position, but I can't figure out how to access that specific element.

My unfinished code:

typedef struct node {
   char grid[MAXGRIDHW][MAXGRIDHW];
   int height;
   int width;
   int parent;
} Node;

bool emptyEnd (Node *b)
{
   int x, y;
   char lastEle = ;

   for (y = 0; y <= b->height; y++) {
      for (x = 0; x <= b->width; x++) {
         if (lastEle == '-') {
            return true;
         } else {
            return false;
         }
      }
   }
}

Solution

  • As outlined in comments:

    • In C, for loops customarily run for (int i = 0; i < limit; i++) so that the limit elements of an array can all be accessed without stepping outside the bounds of the array (which leads to undefined behaviour).

    • Remember, if you have an array SomeType array[10];, the valid indexes have values 0..9; array[10] is not an element that you can access legitimately (though you can form the address &array[10] and make comparisons with it).

    • You code for lastEle is not valid C.

    • Given the requirement that "the function should return true if any of the last column values matches the specified char", your double loop is unnecessary. You only need to check one character in each row, so iterating over the number of rows is sufficient.

    • The original code unconditionally returns from the function on the first iteration of the inner loop in the first iteration of the outer loop — rendering the loops completely unnecessary. You need to keep return true; and remove the else clause completely, adding return false; after the loop bodies.

    • The inner loop in the original code is unnecessary. There is only one last character in each row, so there is no need to check for each character position in the row whether the last character in the row matches a fixed value.

    Here is code that works. It doesn't assume that the grid consists of strings — the byte (char) arrays are not necessarily null-terminated. It doesn't assume that the grid is maximally full (either the height or the width or both can be smaller than MAXGRIDHW). The search function is parameterized by the character to search for so that the code can be tested searching for different characters. I kept the parent element of the structure even though it plays no useful role in the code. I used C99 designated initializers, and C99-style for loops where the loop variable is defined in the loop control. I included the print_grid() function because I wanted to be able to see that the search was correct.

    #include <stdbool.h>
    #include <stdio.h>
    
    enum { MAXGRIDHW = 6 };
    
    typedef struct node
    {
        char grid[MAXGRIDHW][MAXGRIDHW];
        int height;
        int width;
        int parent;
    } Node;
    
    static bool emptyEnd(Node *b, char c)
    {
        for (int y = 0; y < b->height; y++)
        {
            if (b->grid[y][b->width - 1] == c)
                return true;
        }
        return false;
    }
    
    static void print_grid(const char *tag, const Node *np)
    {
        printf("%s: P = %d, H = %d, W = %d\n", tag, np->parent, np->height, np->width);
        for (int r = 0; r < np->height; r++)
        {
            for (int c = 0; c < np->width; c++)
                putchar(np->grid[r][c]);
            putchar('\n');
        }
    }
    
    int main(void)
    {
        Node n =
        {
            .parent = 0, .width = 5, .height = 4,
            .grid =
            {
                { 'a', 'b', 'c', 'd', 'e' },
                { 'b', 'c', 'd', 'x', 'z' },
                { 'p', 'p', '*', '*', '-' },
                { '@', '@', '@', '!', '-' },
            },
        };
        char test[] = "-eA";
    
        print_grid("Test Grid", &n);
    
        for (int i = 0; test[i] != '\0'; i++)
        {
            if (emptyEnd(&n, test[i]))
                printf("At least one last character is '%c'\n", test[i]);
            else
                printf("Not even one last character is '%c'\n", test[i]);
        }
        return 0;
    }
    

    The output from the program is:

    Test Grid: P = 0, H = 4, W = 5
    abcde
    bcdxz
    pp**-
    @@@!-
    At least one last character is '-'
    At least one last character is 'e'
    Not even one last character is 'A'