Задать вопрос

Как в строке удалить ненужный символ и при этом сократить саму строку?

Есть строка, в ней нужно удалить символ таким образом, чтобы остальная строка осталась и размер строки (то есть массива символов), уменьшился. Я использовал calloc для выделения памяти, но не могу додуматься, как при помощи того же realloc сжать строку.

#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h> 
#define _CRT_SECURE_NO_WARNINGS  // от ошибки
#pragma warning(disable : 4996)

int main()
{
	char* ss;
	int n;

	system("chcp 1251");// переходим в консоли на русский язык
	system("cls");// очищаем окно консоли

	printf("Введите длину строки: ");
	scanf("%d", &n);

	ss = (char*)calloc(n, sizeof(char*));  // выделяем память под строку
	gets(ss);
	printf("Введите свое слово (не забываем про длину строки): ");
	scanf("%s", ss);

	for (int i = 0; i < n; i++)
	{
		if (ss[i] != NULL) // проверка на нулевой указатель
		{
			if (ss[i] == '*')  // тот самый символ, который мы ищем
			{
				for (int j = 0; ss[j] != '\0'; j++)
				{
					ss[j] = ss[j++];// здесь я заменял тот символ на следующий, тем самым перекидывая его в конец
				}
			}
		}
		else
		{
			printf("Error... Exit");
			exit(1);
		}
	}

	for (int i = 0; i < sizeof(ss); i++)// ну а тут пытался поменять размер
	{
		if (ss[i] == '\0')
		{
			ss = (char*)realloc(i, sizeof(char*));
			gets(ss);
		}
		else
			break;
	}

	free(ss);
	return 0;
}
  • Вопрос задан
  • 540 просмотров
Подписаться 1 Простой Комментировать
Ответ пользователя Дмитрий Беляев К ответам на вопрос (2)
bingo347
@bingo347
Crazy on performance...
ss = (char*)calloc(n, sizeof(char*)); // выделяем память под строку
Здесь Вы выделяете гораздо больше байт, чем Вам нужно, sizeof(char*) будет равен 8 на 64 битных архитектурах, когда sizeof(char) - 1. Но при этом стоит не забывать про место под '\0' в конце строки.

gets(ss);
printf("Введите свое слово (не забываем про длину строки): ");
scanf("%s", ss);
ss = (char*)realloc(i, sizeof(char*));
gets(ss);
Почитайте, что делает функция gets. Опять же проблема с размерами символа. Ну и у realloc несколько другая сигнатура. И вообще realloc достаточно недешевая операция, не за чем ее делать в цикле много раз над одним указателем, достаточно 1 раз в конце.

if (ss[i] != NULL) // проверка на нулевой указатель
Проверку на NULL нужно делать сразу после аллокации памяти. А вот в цикле ее делать незачем.

ss[j] = ss[j++];// здесь я заменял тот символ на следующий, тем самым перекидывая его в конец
Операция j++ меняет j.

for (int i = 0; i < sizeof(ss); i++)// ну а тут пытался поменять размер
Операция sizeof(ss) даст размер char*, то есть размер указателя, что соответствует 8 на 64 битных архитектурах. Для вычисления длины строки (терминированной символом '\0') есть функция strlen. А в данном случае вообще можно посчитать количество удаленных символов и из него вычислить длину результирующей строки, что будет дешевле.

Ну и по самому алгоритму. Все можно сделать за 1 проход, подсчетом удаляемых символов и перемещением текущего символа на количество удаленных символов назад.
Ответ написан
Комментировать