Как правильно удалить символ из массива char (с преобразованием или без преобразования в строку)?

Вопрос: Извините заранее за любой возможный дублирующий вопрос. Я искал решение для моей ошибки компилятора в течение недели, пробовал различные способы обхода решений из разных ответов, но я все равно получаю некоторые ошибки. В настоящее время я изучаю C++, пытаясь создать программу, которая делает основные вещи, такие как подсчет гласных/согласных, удаление писем и т.д. Все

Вопрос:

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

В настоящее время я изучаю C++, пытаясь создать программу, которая делает основные вещи, такие как подсчет гласных/согласных, удаление писем и т.д. Все работает нормально, пока я не доберусь до части удаления пользовательских писем. В принципе, это почти невозможно сделать, используя функции символов (по моим сведениям), в то время как преобразование в строку, похоже, порождает другие виды ошибок.

Вот фрагмент кода, где я продолжаю получать ошибки:

if (strcmp (service, key4) ==0) { string str(s); cout<<endl<<«Please insert the letter you would like removed from your «<<phrasal<<«:»<<endl; cin>>letterToRemove; s.erase(remove(s.begin(), s.end(),letterToRemove), s.end()); cout<<endl<<s<< «n»<<endl; }

и здесь используется инициализированная переменная I:

int main() { char s[1000], phrasal[10], service[50], key1[] = «1», key2[] = «2», key3[] = «3», key4[] = «4», key5[] = «5», key6[] = «6», key0[] = «0», *p, letterToRemove; int vowel=0, vowel2=0, consonant=0, consonant2=0, b, i, j, k, phrase=0, minusOne, letter, idxToDel; void pop_back(); char *s_bin;

Как вы можете видеть, оригинал ‘s’ является массивом символов. В первом примере кода я попытался преобразовать его в строковый массив (строка str (s)), но это приводит к следующим компиляционным ошибкам:

  • error: запрос для члена ‘erase’ in ‘s’, который имеет тип non-class ‘char [1000]’
  • error: запрос для члена ‘begin’ in ‘s’, который относится к классу non-class ‘char [1000]’
  • error: запрос для члена ‘end’ in ‘s’, который имеет тип non-class ‘char [1000]’
  • error: запрос для члена ‘end’ in ‘s’, который имеет тип non-class ‘char [1000]’

Другое обходное решение, которое я пробовал, было следующим:

if(strcmp(service, key4)==0) {std::string s(s); cout<<endl<<«Please insert the letter you would like removed from your «<<phrasal<<«:»<<endl; cin>>letterToRemove; s.erase(remove(s.begin(), s.end(),letterToRemove), s.end()); cout<<endl<<s<< «n»<<endl; }

Теперь вот смешная часть, я не получаю никаких ошибок для этого, но отладка падает, как только я выбираю функцию удаления пользовательских букв. Вот что он говорит:

“завершение вызова после вызова экземпляра” std :: length_error “what(): basic_string :: _ S_create Это приложение попросило Runtime прекратить его необычным способом. Для получения дополнительной информации обратитесь в службу поддержки приложений”.

Любая помощь будет высоко оценена, застрял на этом один уже неделю!

PS Является ли это нормально, если я или модератор удалят этот вопрос после ответа? Я совершенно уверен, что я не первый, кто спрашивает об этом, но, как упоминалось ранее, я продолжаю получать эти ошибки, даже после ответов на подобные вопросы.

Лучший ответ:

Для массива символов вам нужно использовать std::remove вместо erase и вставить нулевой ограничитель вручную:

auto newEnd = std::remove(std::begin(s), std::end(s), letterToRemove); *newEnd = ‘’; Ответ №1

Если у вас есть общий массив, который может или не может быть разложен на указатель, и у вас есть количество элементов в массиве, но нет другого терминатора (т.е. Это не строка с нулевым символом C-стиля), тогда здесь будет найдено решение:

Сначала я хочу, чтобы вы подумали, как выглядит массив в памяти. Например, если у нас есть массив символов

char array[X] = { ‘A’, ‘B’, ‘C’, ‘D’, … };

Этот массив будет выглядеть так в памяти

+—+—+—+—+——+ | A | B | C | D | … | +—+—+—+—+——+

Если вы хотите удалить букву ‘B’ из этого массива, вы найдете положение буквы, затем скопируете следующую букву (‘C’) на свое место, а следующую следующую букву (‘D’) в следующую букву место и т.д.

Вы можете, конечно, сделать это, используя один цикл:

size_t index_to_remove = 1; // The index of ‘B’ for (size_t i = index_to_remove = 1; i < element_count — 1; ++i) array[i] = array[i + 1];

Вышеприведенный цикл прост, прост в определении и легко проходит через отладчик. Это также не очень эффективно, особенно если массив большой.

Все приведенное выше копирование может быть выполнено с помощью одного вызова функции memmove:

memmove(&array[index_to_remove], &array[index_to_remove + 1], element_count — index_to_remove — 1);

Вышеупомянутый вызов будет в основном делать то же, что и наш цикл выше, но более эффективным и оптимизированным образом.

Используя любой из вышеперечисленных методов, цикл или memmove вызов, оставит массив следующим образом:

+—+—+—+——+ | A | C | D | … | +—+—+—+——+

Важное примечание. Не забудьте изменить element_count после того, как вы “удалили” символ, поэтому он отражает новый размер.

Ответ №2

Для вашего первого решения:

string str(s);

Этот оператор объявляет строку с именем str и содержимое инициализируется содержимым s

Это утверждение, как не влияет на вы возражаете s

Поэтому вам нужно вызвать str.erase() не s.erase()

Оцените статью
Добавить комментарий