Другие языки программирования и технологии

Как правильно присвоить строку двойному массиву СИ. Спасибо! Вопрос внутри

Простите туплю, уже поздний вечер. Так вот, так как на фото выдает ошибку. Компилятор визжит. А как можно? Только через копировальные функции?

И дополнительный вопрос, для любознательных. У меня эта функция будет как хранилище, она должна возвращать этот двойной массив и сохранять в указатель. Так как на фото так хорошо делать? Или есть еще варианты? Я думал может структуру создать, но как я понял в структурах нельзя записывать сразу данные
#include <stdio.h>
#include <stdlib.h>
#define ROWS 19
#define COLS 16
char* get_line(int index) {
static char box[ROWS][COLS] = {
{ '#', '.', '.', '.', '#', '.', '.', '.', '#', '.', '.', '.', '#', '.', '.', '.' },
{ '#', '#', '#', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '.', '#', '.', '.', '#', '#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.' },
{ '.', '#', '.', '.', '#', '#', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '.', '.', '.', '#', '#', '.', '.', '#', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '#', '#', '.', '.', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '#', '.', '.', '#', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '.', '#', '.', '.', '.', '#', '.', '.', '#', '#', '.', '.', '.', '.', '.', '.' },
{ '.', '.', '#', '.', '#', '#', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '#', '.', '.', '#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '.', '.', '.', '#', '#', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '.', '.', '.', '#', '.', '.', '.', '#', '#', '.', '.', '.', '.', '.', '.' },
{ '.', '#', '.', '.', '#', '#', '.', '.', '#', '.', '.', '.', '.', '.', '.', '.' },
{ '.', '#', '#', '.', '#', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '.', '.', '.', '#', '#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.' },
{ '#', '#', '.', '.', '.', '#', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '#', '#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '#', '#', '.', '#', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
{ '#', '#', '.', '.', '.', '#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.' }
};
return box[index];
}
int main(void) {
char** box = (char*)malloc(ROWS * sizeof(char*));
int i, j;
for (i = 0; i < ROWS; ++i) box[i] = get_line(i);
for (i = 0; i < ROWS; ++i) {
for (j = 0; j < COLS; ++j) putchar(box[i][j]);
putchar('\n');
}
free(box);
getchar();
return 0;
}
Макс Круглик
Макс Круглик
93 587
Лучший ответ
Если ты решил валидировать тетраминки прост сравнив их со всеми возможными... то это так себе.
Посчитать количество соседей круче ))
))) )))
))) )))
73 465
Ивау Вау так их всего 19, и вроде бы ты так и советовал их валидовать, я ж по твоему совету иду)) Я написал ф-цию которая считают ровно одну тетраминку, затем где б фигурка не стояла спускает ее на координату 0х0, те вверхний левый угол, ну теперь осталось сравнить ее с 19ю имеющимися и так каждую.

что значит посчитать количество соседей? как я и сказал я думал ты так и советовал делать
Ивау Вау я так понял же нельзя создавать глобальные переменные же
Ивау Вау И вообще ты спишь когда-то? я надеялся что ты не ответишь)
))) ))) Да, все верно, что надо сохранить эти фигуры в двойном указателе, где в каждом по одной фигурке.
Но тебе ж надо отвалидировать не только сами тетраминки, а лишние символы.
Сначала считывая ГНЛом проверяешь, равно ли количество считаемых символов 4, и каждый 5-ый должен быть равен 0, думаю сам понимаешь почему.
Как проверил что все норм, ты сохраняешь эти тетраминки в двойной указатель. Там ты проверяешь:
- на лишние символы, ничего кроме # и точки.
- количество решеток вообще в фигурке, не должно превышать 4.
- сами тетраминки, их соседей должно быть 6 или 8(исключение для квадрата) вроде бы.
Подсчет соседей это берешь # и смотришь вверх вниз вправо влево, есть ли около него еще одна #, если есть одна или несколько, то плюсуешь столько то раз.
Попробуй заменить тип на char* ttrs[16].
UPD: это тоже не поможет, т. к. тебе придётся возвращать этот массив из функции, а он живёт только до конца функции, а потом возвращаемый указатель будет указывать на невыделенную область памяти, т. е. ниже конца стека. Можешь выделять его на куче через malloc (или new, если речь о плюсах), но тогда придётся следить за своевременным освобождением памяти.

Я не очень понимаю, что такое "хранилище", но если это какие-то константные строчки типа шаблонов тетрамино, то их проще сохранить в глобальных переменных и инициализировать в main-е. А то у тебя на каждый вызов будет копия создаваться.
Ивау Вау да я так думал, но в задании вроде как нельзя создавать глобальные переменные. Ща еще раз перепроверю
По поводу функции char **get_arr() не прокатит. Нужно читать время жизни переменной. В данном случае вы создаете массив в функции. Потом при выходе из функции массив уничтожается (он конечно не сразу удалит данные в нем, но к этому массиву уже не стоит обращаться так как другие переменные будут создаваться именно в месте где был массив) и вы возвращаете из функции указатель на массив, который удалится при выходе из функции.

char **arrayOfChar = get_arr();
int x = 10; // вот эта переменная наверняка уже попортит массив созданный в функции, нужно копаться и проверять, но я всего лишь к тому что так не делается
Можно попробовать использовать ключевое слово static(я на С++ учился и не знаю есть ли оно в С)

static char ttrs[19][16] = {
"#...#...#...#...",
"####....",
...,
...
};
return ttrs; // В таком случае возможно прокатит.

strcpy - именно через эту функцию и нужно либо в цикле ручками имитируя функцию strcpy.

В комментах допишу ответ, так как все еще не прокатывает даже со static.
Cерёжа =)
Cерёжа =)
15 408
Cерёжа =) Это для с++, но если заменить библиотеку на stdio и std::cout на printf то это уже будет С
Cерёжа =) Ошибка была в том что когда создаете двумерный массив. то возврат указатель на указатель это неправильно. Потому что расчет следующего элемента в двумерном массиве идет при помощи знания сколько он в ширину. То есть array[0] начнется с нуля, а array[1] с 16 символа (на самом деле с 17 и об этом написал ant man так как еще будет завершающий ноль), а array[2] будет начинаться с 32 символа. А указател на указатель будет считывать не строку по адресу, а указатель на символ. А вот если создать массив указателей, как я это и сделал, то тогда все работает так как в массиве считывается указатель, который в свою очередь указывает на строку.
Cерёжа =) Но все равно такой подход не используют так как привыкли что область видимости переменной и время ее жизни не выходит за пределы блока. static же используют тогда, когда нужно что бы при последующем входе в функцию эта переменная сохраняла свое предыдущее значение. Например подсчет вызовов функции (пример тупой, так как не сильно то это нужно считать сколько раз функцию вызвали).
int count()
{
static int countOfCall = 0;
countOfCall++;
return countOfCall;
}
xxx
Ивау Вау ну я понял что ты знаешь но лень писать, окей
"сразу" записывать данные в структуры можно. это называется инициализацией. только надо, естественно, создать экземпляр структуры сначала.

для текущей же задачи можно создать ВНЕШНЮЮ переменную (т. е. объявить ее вне функций). и инициализировать ее. как уже в другом ответе:

char ttrs[19][16] = {
"#...#...#...#...",
"####....",
...,
...
};

только надо принять во внимание, что литералы в двойных кавычках включают в себя завершающий строку нулевой элемент, а значит для их хранения длина массива должна быть не 16, а 17.

и перестань уже возвращать ссылки на локальные переменные в функции. ОНИ УНИЧТОЖАЮТСЯ, указатель по возвращении из функции будет указывать в освобожденную память!
HM
Hovo Manukyan
1 198
Удали комп
Ивау Вау прости нет не удалю