Creating a dynamically allocated struct with a 2D

2020-05-03 11:43发布

问题:

I'm trying to scan in a grid of letters. cases is the number of letter grids and r, c are for number of rows and columns of each grid. I figured I could create an array of structs with 2D arrays inside. I've been working on this for a few hours now and it's still giving me problems:

  • Warnings:

    • Warning C4477 (Line 12) - ‘scanf_s’ : format string ‘%s’ requires an argument of type ‘char*’, but variadic argument 1 has type ‘int’
    • Warning C4473 (Line 12) - ‘scanf_s’ : not enough arguments passed for format string
  • Errors:

    • Compiler Error C2274

    • Compiler Error C2461

The code:

scanf_s("%d", &cases);
struct grid { 
    char **grid; 
};
struct grid *grids = (struct grid*)malloc(cases * sizeof(struct grid));

for (i = 0; i < cases; i++) {
    scanf_s("%d %d", &r, &c);
    grids[i].grid = (char**)malloc(sizeof(char*) * r);
    for (k = 0; k < r; k++) {
        grids[i].grid[k] = (char*)malloc(sizeof(char) * (c+1));
        scanf_s("%s", grids[i].grid[k], (c+1));
    }           
}

回答1:

I had to tweak a little bit the code in the question, also to add some missing parts (that should have also been provided, btw), to get a compilable (using VStudio2010) piece.

main00.c:

#include <stdio.h>
#include <stdlib.h>


struct grid { 
    char **grid; 
};


int main() {
    int cases, r, c, k, i;
    struct grid *grids;

    scanf_s("%d", &cases);
    grids = (struct grid*)malloc(cases * sizeof(struct grid));

    for (i = 0; i < cases; i++) {
        scanf_s("%d %d", &r, &c);
        grids[i].grid = (char**)malloc(sizeof(char*) * r);
        for (k = 0; k < r; k++) {
            grids[i].grid[k] = (char*)malloc(sizeof(char) * (c + 1));
            scanf_s("%s", grids[i].grid[k], (c + 1));
        }           
    }
    return 0;
}

Notes:

  • You were compiling the code as C++ (as @alk noticed), and this is what completely threw you off course. In order to fix that either:
    • Set your file extension to .c (and you can leave the VStudio defaults in term of compilation; that way it will compile each source file using the appropriate compiler based on its extension)
    • Explicitly compile the source file as C. You can set that from VStudio Project Properties -> C/C++ -> Advanced -> Compile As, and choosing Compile as C Code. For more info, visit [MS.Docs]: /Tc, /Tp, /TC, /TP (Specify Source File Type). Personally, I think that the former option is more straightforward
  • Move the variable declarations before any statements (I think this might have been a candidate for setting the C++ compiler). This was a restriction for older C standards (I doubt that it still stands), but (VStudio 2010) C compiler still enforces it (at least by default)