Sometimes it works, and sometimes it doesn't, the problem is somewhere in the DeleteWords function, when it doesn't work, it gives an error

 Вызвано исключение: нарушение доступа для чтения. ptr было 0x2A2A2A2A. 

Indicates the string while (*ptr != '\0' && *ptr != NULL && *ptr!='\n') Code with Ukrainian comments:

 // Двохзв'язний список #include "pch.h" #include <stdlib.h> #include <iostream> #include <string> using namespace std; #define K 300 struct Node // Структура, яка є основою списку { char array[K]; // Значення array буде передаватися у список Node *Next, *Prev; // Вказівники на адреси попереднього і наступного елементів списку }; class List // Створємо клас список { public: Node *Head, *Tail; // Вказівники на адреси початку та кінця списку List() :Head(NULL), Tail(NULL) {}; // Ініціалізуємо адреси як пусті ~List(); // Прототип деструктора void ShowLast(); // Прототип функції відображення списку на екрані з останнього елементу void ShowFirst(); // Прототип функції відображення списку на екрані з першого елементу void Add(char x[K]); // Прототип функції додавання елементів у список void DeleteWords(char letter); // Прототип функції з індивідуального завдання }; List::~List() // Деструктор { while (Head) // Поки за адресою на початок списка щось є { Tail = Head->Next; // Резервна копія адреси наступної ланки списку delete Head; // Очищення пам'яті від перошої ланки Head = Tail; // Зміна адреси початку на адресу наступного елемента } } void List::Add(char x[K]) { Node *temp = new Node; // Виділяємо пам'ять під новий елемент структури temp->Next = NULL; // Вказуємо що початкове значення за даною адресою - пусте strcpy(temp->array, x); // Записуємо значення у структуру if (Head != NULL) // Якщо список не пустий { temp->Prev = Tail; // Вказуємо адресу попереднього елементу за хвостом у відповідне поле Tail->Next = temp; // Вказуємо адресу наступного елементу за хвостом Tail = temp; // Міняємо адресу хвоста } else // Якщо список пустий { temp->Prev = NULL; // Попередній елемент вказує у пустоту Head = Tail = temp; // Голова=Хвіст=*той елемент, який ми тільки що додали* } } void List::ShowLast() { // ВИВОДИМО СПИСОК З КІНЦЯ Node *temp = Tail; // Тимчасовий вказівник на адресу останнього елементу while (temp != NULL) // Тимчасово вказуємо на адресу першого елементу { cout << temp->array << " "; // Виводимо значення на екран temp = temp->Prev; // Вказуємо, що потрібна адреса попереднього елементу cout << endl; } cout << endl; } void List::ShowFirst() { Node *temp = Tail; // Тимчасовий вказівник на адресу останнього елементу // ВИВОДИМО СПИСОК З ПОЧАТКУ temp = Head; // Тимчасово вказуємо на адресу першого елементу while (temp != NULL) // Допоки не зустрінемо пусте значення { cout << temp->array << " "; // Виводим всі значення на екран temp = temp->Next; // Зміна адреси на адресу наступного елементу cout << endl; } cout << endl; } void List::DeleteWords(char letter) { Node *temp = Tail; // Тимчасовий вказівник на адресу останнього елементу // ВИВОДИМО СПИСОК З ПОЧАТКУ temp = Head; // Тимчасово вказуємо на адресу першого елементу while (temp != NULL) // Допоки не зустрінемо пусте значення { char *ptr = temp->array; // Вказівник на початок речення char *dod = temp->array; // Додатковий вказівник на початок речення while (*ptr != '\0' && *ptr != NULL && *ptr!='\n') // Допоки не кінець речення { if (*ptr == ' ') // Якщо вказівник потрапив на пробіл { dod = ptr; // Додатковий вказівник переносимо на це місце ptr++; // Шукаємо далі кінець слова } if (*ptr == letter) // Якщо вказівник потрапив на нашу буку { while (*ptr != ' ') // Допоки не кінець слова { ptr++; // Шукаємо кінець слова } while (dod != ptr) // Допоки додатковий вказівник не дійшов до кінця слова { *dod = '*'; // Замінюємо слово на "*" dod++; // Йдемо до кінця слова } ptr++; continue; // Рухаємо основний вказівник } ptr++; // Рухаємо основний вказівник } temp = temp->Next; // Зміна адреси на адресу наступного елементу cout << endl; } cout << endl; } int main() { system("CLS"); List list; // Об'явимо змінну, ти якої - список char array[K]; for (int i = 0; i < 5; i++) // Введемо елементи списку { cout << "Enter " << i+1 << " element of the list:" << endl; gets_s(array); list.Add(array); } list.ShowFirst(); // Відображаємо список з початку на екрані char letter; cout << "Enter the letter: "; cin >> letter; list.DeleteWords(letter); list.ShowFirst(); system("PAUSE"); return 0; } 
  • Decided to add '\ 0': while (* ptr! = '' && * ptr! = ',' && * ptr! = '\ 0') - Get Right

1 answer 1

Judging by the code, you do not delete words from the character array, but replace them with asterisks.

The following loop inside the if-sentence has undefined behavior

  while (*ptr != ' ') // Допоки не кінець слова { ptr++; // Шукаємо кінець слова } 

since there is no check for the end of the line, that is, for the '\0' character. Therefore, the ptr may move beyond the character array.