@Korifa

Как решить эту задачу си?

Подскажите, пожалуйста, как решить следующую задачу.
Надо заполнить массив текстом с клавиатуры, потом заменить строчку/строчки в этом массиве текстом в переменной.
Я объявил переменную массив char
Потом с помощью getchar() в цикле заполнил массив.
Следующим шагом подумал проверять каждый символ массива, если совпадает с искомым, то во внутреннем цикле проверять строчку до конца.
В общем у меня не получается увеличить обьем массива с помощью realloc. Чтобы я мог заменить или вставить строчку.
Realloc возвращает пустой блок памяти, не сохраняет данные?
Я думал увеличу обьем массива и перенесу часть текста в права, чтобы вставить новый текст.
или так не получиться и надо копировать?
  • Вопрос задан
  • 287 просмотров
Решения вопроса 1
bingo347
@bingo347
Crazy on performance...
Для начала нужно понимание, что памятью на стеке управляет компилятор, и для каждой функции эта память имеет фиксированный размер. А все потому, что в ассемблере, в который скомпилится наш C код нет переменных, вместо них компилятор просто проставит смещения от указателя на конец стека на старте функции. Именно по этому компилятору важно знать размеры всех сущностей на стеке.
Изменить этот размер в рантайме нельзя, поэтому единственный способ решить эту задачу с массивом символов на стеке - выделить массив с достаточным запасом памяти, чтоб хватило и на исходную строку и на вставляемую подстроку.
А вот память в куче динамическая. И все аллокации работают именно с ней. И главное мы ее можем выделять в рантайме по мере надобности.
Учитывая, что массивы в C - это по сути сахар над указателями, то смело можете заявлять своему преподу, что указатель на несколько подряд идущих char в куче и массив char - это одно и то же.

Вообще, по нормальному я бы объявил структуру вроде такой:
typedef struct {
	char* buffer;
	size_t capacity;
	size_t length;
} string;
и дальше бы работал с ней, заодно разбив код на небольшие функции. Но преподы программирования народ от разработки далекий, и кроме своих лабараторок в программировании не бум-бум в большинстве своем. А в комментах к вопросу было про то, что структуры нельзя...
Поэтому решение в лоб и в стиле универских лаб:
#include <stdio.h>
#include <stdlib.h>

int main() {
	size_t capacity = 1 << 4; // на старте буду выделять 16 байт
	size_t length = 0; // строка пока пустая, поэтому 0
	char* str = malloc(capacity);
	if (str == NULL) { // с памятью в куче может и облом быть
		return 1; // вернем код ошибки
	}
	printf("Write string and press ENTER to continue:\n");
	while(1) { // читать символы будем до скончания веков ))
		char c = getchar();
		if(c == 13 || c == 10) break; // ну или пока юзер не нажмет ентер
		length++; // увеличим счетчик символов
		if(length > capacity) { // если новый символ не влазит в выделеную память
			capacity <<= 1; // то удвоим ее
			char* new_str = realloc(str, capacity); // и перевыделим
			if (new_str == NULL) { // опять чекнем, вдруг облом
				free(str); // ресурсы надо освобождать
				return 1; // вернем код ошибки
			}
			str = new_str; // в str теперь невалидный указатель, можем его заменить
		}
		str[length - 1] = c; // запомним считанный символ
	}
	// Здесь решение с вставкой подстроки
	// с учетом того, что у нас строка str
	// с длиной length и выделеной памятью под нее capacity
	free(str); // ресурсы надо освобождать
	return 0; // вернем код успешного завершения
}
с самой вставкой подстроки надеюсь справитесь?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 нояб. 2024, в 03:54
1500 руб./за проект
22 нояб. 2024, в 02:56
10000 руб./за проект
22 нояб. 2024, в 00:55
500 руб./за проект