Программирование C - размер массива на основе аргумента командной строки

Я пытаюсь создать сетку для настольной игры, я знаю максимальный размер доски, однако он также может быть меньше в зависимости от того, что пользователь вводит в командной строке. Я сделал следующую программу, она успешно компилируется, но когда я пишу размеры в командную строку, она говорит: «Ошибка сегментации (сброс ядра)». Может ли кто-нибудь сказать мне, что я сделал неправильно?

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

#define BOARD_WIDTH 80
#define BOARD_HEIGHT 52

int i;
int j;
int width;
int height;
int generations;
int grid[BOARD_WIDTH][BOARD_HEIGHT];

int main(int argc, char *argv[])
 {

if (argc < 2)
{
 printf("Not enough arguments entered\n");
 exit(1);
 }
else
{
 width = atoi(argv[2]);
 height = atoi(argv[3]);
 generations = atoi(argv[4]);
 }
for(i=0;i<width;i++)
for(j=0;j<height;j++)

printf("%2d", grid[i][j]);
}

person Ibz    schedule 14.05.2013    source источник
comment
Какая у вас командная строка? Ваша программа рухнет, если вы введете только 2 аргумента.   -  person Klas Lindbäck    schedule 14.05.2013
comment
@klas моя командная строка ./gol 7 6 5   -  person Ibz    schedule 14.05.2013
comment
Затем вы должны atoi argv[1], argv[2] и argv[3]. Прочтите и следуйте указаниям в ответе Салгара.   -  person Klas Lindbäck    schedule 14.05.2013
comment
@KlasLindbäck хорошо, спасибо большое   -  person Ibz    schedule 14.05.2013


Ответы (4)


Много вещей

Вы установили фиксированные BOARD_WIDTH и BOARD_HEIGHT при объявлении переменной, поэтому, если вы передадите более высокие значения, чем в командной строке, это не сработает.

Но в основном что вы пытаетесь напечатать? Вы не инициализировали grid чем-то конкретным, поэтому вы печатаете случайную память.

Во-первых, вам нужно будет инициализировать свою сетку, используя «новый»: посмотрите здесь этот Создать 2D-массив с размерами переменного размера

Затем вам нужно будет инициализировать эти переменные чем-то. Затем вы можете их распечатать.

Было бы легче помочь вам, если бы вы показали нам, что вы передали в программу. Но все вышеперечисленные причины — это начало.

Также произойдет сбой, если вы не передадите программе 3 аргумента, поскольку вы используете 3.

Хотя вы используете argv[2] для argv[4] — вы должны использовать argv[1] для argv[3]. Таким образом, в текущем состоянии он рухнет, если вы не передадите 4 аргумента.

person Salgar    schedule 14.05.2013
comment
ТАКЖЕ, вы проверяете, равен ли argc ‹ 2, но используете 3! должно быть, если argc ‹ 4 - person Salgar; 14.05.2013
comment
спасибо, теперь я использую argv[1] для argv[3]. Я передаю это в программу ' ./gol 7 6 5 ', ожидая появления сетки шириной 7 и высотой 6, я не понимал, что мне нужно инициализировать сетку. извините, я новичок в программировании. Я не уверен, что вы имеете в виду, я должен инициализировать эти переменные чем-то, прежде чем распечатывать их. - person Ibz; 14.05.2013
comment
grid имеет файловую область, поэтому она инициализируется всеми нулями. new — это C++, но вопрос помечен как C. - person Daniel Fischer; 14.05.2013
comment
@DanielFischer, да, это значит, что мне не нужно инициализировать сетку, я хочу оставить всю сетку пустой, как в пробелах, и напечатать границу снаружи - person Ibz; 14.05.2013
comment
@Ibz Пробелы не равны нулю. Без явной инициализации grid инициализируется всеми нулями, поэтому, если вы хотите что-то еще в нем, вы должны установить его в какой-то момент. - person Daniel Fischer; 14.05.2013

Убедитесь, что в argv[2], argv[3], argv[4] что-то есть, прежде чем использовать их. Вероятно, следует читать if(argc < 5) { exit(1); }

person edtheprogrammerguy    schedule 14.05.2013

У вас может быть 2 подхода к вашей проблеме: во-первых, вы можете создать массив максимального размера и использовать только активные элементы, во-вторых, вы можете создавать массив каждый раз при запуске игры. Для 2-го варианта вам необходимо предоставить входную информацию для размера игры. Первый метод уже реализован вами (поскольку у вас есть статическая таблица доски), если вы хотите создавать его каждый раз при запуске игры, просто создайте его после изменения строковых значений на целые числа:

a = atoi(argv[2])
b = atoi(argv[3])
i = int[a][b]
person cerkiewny    schedule 14.05.2013
comment
как вы думаете, метод, который я начал использовать, проще - person Ibz; 14.05.2013
comment
Основное различие между этими методами указывает на варианты использования. Ваш метод хорош, если таблица будет часто использоваться с разными размерами во время одного выполнения программы (программа будет работать быстрее, так как не будет использоваться дополнительное выделение памяти), но если Вы собираетесь использовать таблицу только один раз, лучше выделить ее один раз со значениями аргументов. - person cerkiewny; 14.05.2013

Я собираюсь предположить, что код, который вы представляете, является просто фрагментом. Если это так, я подозреваю, что ваша главная проблема заключается в том, что вы обращаетесь к неправильным индексам для своих аргументов. Первый аргумент имеет индекс один (имя файла равно нулю). argc — это общее количество аргументов, включая имя файла.

Предполагая, что все аргументы, которые вы используете, представлены во фрагменте кода, у вас должно быть в общей сложности четыре индекса с шириной, высотой и поколениями, имеющими индексы 1, 2 и 3 соответственно.

person corahm    schedule 14.05.2013