我现在正试图学习C并且遇到了一个我自己无法解决的任务。这是一个简单的扫雷实施。
简短说明该程序应该做什么: 它通过命令行获取输入文件,一次打开它们,为每个创建扫雷字段,如果打开多个文件,程序将它们格式化为一个文件。我不想一个接一个地格式化它们,我想使用动态二维数组,这样矩阵就可以扩展而不会丢失已经保存的地雷。
每个输入文件都具有相同的构建:
3\t5\n
0\t3\n
3\t7\n
...
第一行总是表示n x m矩阵的大小,所有后续行都是地雷的坐标。
到目前为止,这是我的代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct game{
int n;
int field[];
}game;
int read_files(char **input, int length);
int make_field(char *input, int i, int *ptr);
void increment(int i, int j, game);
int is_inside_bounds(int i, int j, game);
void free_field();
void safe_field();
int main(int argc, char **argv){
read_files(argv, argc);
return 0;
}
//read_files reads all files given to the programm via the commandline
int read_files(char **input, int length){
int i= 1;
char string[20]; //input goes into this via fgets
int filecount = 0; //counts the amount of files
int fieldptr[100]; // is an int array with the purpose of memorizing the size of all gamefields I create
int j = 0;
for (; i< length-1; i++){
FILE *in;
if(!(in = fopen(input[i], "r"))){
fprintf(stderr, "File not found.\n");
err = 2;
return err;
}
while (fgets(string,20,in)){
make_field(string, filecount, fieldptr); //gives all relevan info to the make_field function
j++;
}
fclose(in);
filecount++;
}
return 0;
}
int make_field(char *string, int file, int *fieldptr){
struct g = NULL;//this is my problem
int g.field = NULL;//this too
char delimiter[] = "\t\n"; //the input file cuts the chars with \n and \t
char *ptr; //needed for strtok
file= file * 2; //this is used for the filehandling
ptr = strtok(string, delimiter);
int a = atoi(ptr); //cast to int so I have the gamefield size as a int
ptr = strtok(NULL, delimiter);
int b = atoi(ptr); //cast to int so I have the gamefield size as a int
if (fieldptr[file] == 0 && file == 0){//init field
fieldptr[0] = a; //memorize first call
fieldptr [1] = b;
g.field = malloc(a * sizeof(int*));
if (NULL == field){
fprintf(stderr, "Memory error.\n");
return 3;
}
for(int j = 0; j < a; j++){
g.field[j] = malloc(b * sizeof(int));
if(NULL==g.field[j]){ allocated
fprintf(stderr, "Memory error.\n");
return 3;
}
}
}else if (fieldptr[file] == 0 && file != 0){ //if it is the first line and but not the first file
field = realloc(g.field, a * sizeof(int*));
if (NULL == field){
fprintf(stderr, "Memory error.\n");
return 3;
}
for(int j = 0; j < a; j++){
field[j] = realloc(field[j], b * sizeof(int));
if(NULL==g.field[j])
fprintf(stderr, "Memory error.\n");
return 3;
}
}
fieldptr[file] = a; //filehandling memory
fieldptr[file+1] = b;
}else if(fieldptr[file] != 0 && file == 0){ //fill the mines +indicators into the array
g.field[a][b] = -1;
int m;
for (m = -1; m <= 1; m++) {
int n;
for (n = -1; n <= 1; n++) {
increment(a + m, (fieldptr[file+b]) + n, g);
}
}
}else if (fieldptr[file] != 0 && file != 0){ //fill the mines +indicators into the bigger array
g.field[a][fieldptr[file+b]] = -1;
int m;
for (m = -1; m <= 1; m++) {
int n;
for (n = -1; n <= 1; n++) {
increment(a + m, (fieldptr[file+b]) + n, g);
}
}
}
return field; //not sure about the return yet
}
void increment(int i, int j, game *g) { //increments the neighbours of the minefield
if (is_inside_bounds(i, j, g) && field[i][j] != -1) {
++g.field[i][j];
}
}
int is_inside_bounds(int i, int j, game *g) { //checks if the access of increment is inside the array
int nLines = sizeof(g.field) / sizeof(g.field[0][0]);
int nColumns = sizeof(g.field[0]) / sizeof(field[0][0]);
return i >= 0 && i < nLines && j >=0 && j < nColumns;
}
来自java,在我看来这应该可行,但我真的不知道C如何与多维数组一起工作。任何人都可以指出我正确的方向吗?
编辑:
gcc有以下输出:
error: invalid use of flexible array member
g.field = realloc(g.field, a * sizeof(int*));
In function ‘increment’:
note: the ABI of passing struct with a flexible array member has changed in GCC 4.4
void increment(int i, int j, game g) {
所以我的问题是我不知道如何以正确的方式声明和使用数组。
答案 0 :(得分:1)
struct g = NULL;//this is my problem
int g.field = NULL;//this too
你是对的,这是你的问题
1)您的意思是game g
而不是struct g
2)如果没有指针,则无法使用NULL
:
game *g = NULL; /* Ok */
3)您无法访问未初始化g.field
(struct
)
g
)
更多问题:
g.field = malloc(a * sizeof(int*));
您不能将malloc
与灵活的数组成员一起使用,您需要为整个struct
保留空间,包括灵活数组成员的大小:
game *g = malloc(sizeof(*g) + (n * sizeof(int)));
或更好
game *g = malloc(sizeof(*g) + (n * sizeof(g->field[0])));
注意sizeof(int)
而不是sizeof(int *)
,您要为n
int
预留空间,而不是int
的
或将field
更改为
typedef struct game {
int n;
int *field;
} game;
为了直接使用malloc
成员。