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

Есть строка, в ней нужно удалить символ таким образом, чтобы остальная строка осталась и размер строки (то есть массива символов), уменьшился. Я использовал 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;
}
  • Вопрос задан
  • 341 просмотр
Пригласить эксперта
Ответы на вопрос 2
CityCat4
@CityCat4
Внимание! Изменился адрес почты!
Минутку, я кажется когда-то такую задачу решал... Вот.
/*-------------------------------------------------------------------------
            Unescape string againts some character

            Call: void strunescape(char *source, char symbol);
            Args: source - source string, is subject to change!
                  symbol - unescaping symbol

            Source string MUST be finished by \0'.
-------------------------------------------------------------------------*/
#include "make.h"

// Main function

void strunescape(char *source, char symbol)
{
  register int i = strlen(source);
  register int j;

  for(j = 0;j <= i;j++)
   if (source[j] == symbol)
     memmove(&source[j], &source[j + 1], i - j + 1);
}


Смысл в чем - при уменьшении строки ты ее просто дергаешь к голове в той же самой области памяти. И так до тех пор, пока все вхождения symbol не будут обнаружены.
Ответ написан
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 проход, подсчетом удаляемых символов и перемещением текущего символа на количество удаленных символов назад.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы