Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Указатель на конец последовательности


Автор: Fally 5.10.2007, 17:26
Здравствуйте. Только начинаю свой путь в С++. Ситуация такая, есть последовательность из структур такого вида и два указателя (на начало и конец последовательности) а также строковая переменная в которую на некоторое время считывается ввод пользователя:
Код

string _userEnter;
struct Node {
        string Word;
        Node *prev;
        Node *next;
        Node(string text) {
            this->Word = text;
            this->prev =    0;
            this->next =    0;
        }
    };
Node *_wordList;
Node *_wordListEnd;

Всё это дело необходимо завернуть в класс, я решил это оформить сразу в его конструкторе:
Код

TextEditor() {
            char Symbol      =  '~';
            char predSym     =  '~';
            unsigned int countWords = 0;
            bool isFirstWord = true;
            if(this->_userEnter.empty()) {
                cout << "Vvedite stroku: ";
                while(cin.get(Symbol)) {
                    if(isalnum(Symbol)) {
                        this->_userEnter.push_back(Symbol);
                    } else if(isspace(Symbol)) {
                        if(isFirstWord && !this->_userEnter.empty()) {
                            isFirstWord = false;
                            addFirstWord(this->_userEnter);
                            countWords++;
                        } else {
                            if(this->_userEnter.empty()) {
                                continue;
                            }
                            Node *newWord = new Node(this->_userEnter);
                            Node *oldWordListEnd = this->_wordListEnd;
                            newWord->prev = oldWordListEnd;
                            oldWordListEnd->next = newWord;
                            this->_wordListEnd = newWord;
                            countWords++;
                        }
                        this->_userEnter.clear();
                    } else if(TextEditor::EOI == Symbol) {
                        if(0 == countWords) {
                            addFirstWord(this->_userEnter);
                            countWords++;
                        } else { // именно с этого блока и начинаются проблемы
                            Node *newWord = new Node(this->_userEnter); 
                            Node *oldWordListEnd = this->_wordListEnd;
                            newWord->prev = oldWordListEnd;
                            oldWordListEnd->next = newWord;
                            this->_wordListEnd = newWord;
                        }
                        break;
                    } else {
                        this->_userEnter.clear();
                        continue;
                    }
                }
            }
        };
void addFirstWord(string fw) {
        this->_wordList    =    new Node(fw);
        this->_wordListEnd = this->_wordList;
};

Проблема состоит в том, что при добавлении последнего слова, сразу после которого идёт точка не назначается указатель на последний элемент последовательности, а точнее он не изменяется. До сих пор не могу понять в чём причина. Вот этот "кусок" кода, в котором и происходит некорректная работа:
Код

if(0 == countWords) {
    addFirstWord(this->_userEnter);
    countWords++;
} else { // именно с этого блока и начинаются проблемы
    Node *newWord = new Node(this->_userEnter); 
    Node *oldWordListEnd = this->_wordListEnd;
    newWord->prev = oldWordListEnd;
    oldWordListEnd->next = newWord;
    this->_wordListEnd = newWord;
}

Испробовал уже кучу вариантов, ничего не получилось.
Пожалуйста, помогите разобраться с этим ужасным глюком.
Заранее благодарен.
P.S. К сожалению, различные контейнеры использовать запрещено. 

Автор: DjoNIK 5.10.2007, 18:20
А  разве EOF не входит в область определения, при которой isspace возвращает true?

Автор: Fally 5.10.2007, 18:46
в смысле??? Я EOF не использую... а если вы имели ввиду EOI, то вот определение:
Код

static const char EOI = '.';

Автор: wils0n 6.10.2007, 04:32
Не уверен, что понял Вашу проблему
Цитата

при добавлении последнего слова, сразу после которого идёт точка не назначается указатель на последний элемент последовательности

правильно ли я понял, что последний элемент не добавляется? Или как?   smile 
а как Вы выявили проблему. Я имею ввиду, как Вы её обнаружили? Дебаггером или вывели список на экран? Если второе, то пожалуйста код, который это делает.

Автор: zkv 6.10.2007, 04:53
Fally, давай полный текст программы, чтобы можно было компилировать. 
Цитата(Fally @  5.10.2007,  17:26 Найти цитируемый пост)

Всё это дело необходимо завернуть в класс, я решил это оформить сразу в его конструкторе:

в конструкторе обычно выполняется инициализация объекта а не вся программа   smile 
Код не очень удобен для восприятия, мягко говоря. smile 

Автор: Fally 6.10.2007, 16:58
Цитата(zkv @  6.10.2007,  04:53 Найти цитируемый пост)
в конструкторе обычно выполняется инициализация объекта а не вся программа   smile 

Просто ввод строки, это в принципе и есть инициализация объекта ;) Дальше будет куча действий над этой строкой, которую уже реализовывал через методы...
Код



Цитата(wils0n @  6.10.2007,  04:32 Найти цитируемый пост)
а как Вы выявили проблему. Я имею ввиду, как Вы её обнаружили? Дебаггером или вывели список на экран? Если второе, то пожалуйста код, который это делает. 

Выявил эту проблему, при помощи метода вывода введённого текста на экран (выводить можно и в обратном порядке), при выводе в том виде, в каком строка была введена всё нормально, а как только производиться вывод задом наперёд, то сразу замечается пропажа последнего слова, т.е.:
Ввели: mama i papa.
Вывод: mama i papa.
Вывод в обратном порядке: i mama.

Вот код всего класса:
Код

#include "stdafx.h"
#include <iostream>
#include <cctype>
#include <string>
using namespace std;

class TextEditor {
    public: 
        static void drawLegend() {
            cout << "Operacii: " << endl;
            cout << "0 - Vvesti stroku;" << endl;
            cout << "1 - Poisk slova;" << endl;
            cout << "2 - Zamena slova;" << endl;
            cout << "3 - Zamena vseh odinakovyh slov;" << endl;
            cout << "4 - Vstavit' slovo v nachalo stroki;" << endl;
            cout << "5 - Vstavit' slovo v konec stroki;" << endl;
            cout << "6 - Vstavit' slovo v seredinu stroki;" << endl;
            cout << "7 - Udalit' slovo iz stroki;" << endl;
            cout << "8 - Udalit' vse odinakovye slova iz stroki;" << endl;
            cout << "! - Vyvesti vvedennuyu stroku na ekran;" << endl;
            cout << "@ - Vyvesti vvedennuyu stroku na ekran zadom na pered;" << endl;
            cout << "# - Vyvesti legendu esche raz;" << endl << endl;
            cout << "9 - Vyhod iz programmy;" << endl;
        };
        static const char EOI = '.';
        TextEditor() {
            char Symbol      =  '~';
            char predSym     =  '~';
            unsigned int countWords = 0;
            bool isFirstWord = true;
            if(this->_userEnter.empty()) {
                cout << "Vvedite stroku: ";
                while(cin.get(Symbol)) {
                    if(isalnum(Symbol)) {
                        this->_userEnter.push_back(Symbol);
                    } else if(isspace(Symbol)) {
                        if(isFirstWord && !this->_userEnter.empty()) {
                            isFirstWord = false;
                            addFirstWord(this->_userEnter);
                            countWords++;
                        } else {
                            if(this->_userEnter.empty()) {
                                continue;
                            }
                            Node *newWord = new Node(this->_userEnter);
                            Node *oldWordListEnd = this->_wordListEnd;
                            newWord->prev = oldWordListEnd;
                            oldWordListEnd->next = newWord;
                            this->_wordListEnd = newWord;
                            countWords++;
                        }
                        this->_userEnter.clear();
                    } else if(TextEditor::EOI == Symbol) {
                        if(0 == countWords) {
                            addFirstWord(this->_userEnter);
                            countWords++;
                        } else {
                            Node *newWord = new Node(this->_userEnter);
                            Node *oldWordListEnd = this->_wordListEnd;
                            newWord->prev = oldWordListEnd;
                            oldWordListEnd->next = newWord;
                            this->_wordListEnd = newWord;
                        }
                        break;
                    } else {
                        this->_userEnter.clear();
                        continue;
                    }
                }
            }
        };
        void printInput(bool reverse = false) {
            Node *pv = reverse ? this->_wordListEnd : this->_wordList;
            while(pv) {
                std::cout << pv->Word << " ";
                pv = reverse ? pv->prev : pv->next;
            }
            cout << endl << endl;
        };
        void searchWord() {
            char Sym = '~';
            string search_string;
            cout << "Vvedite iskomoe slovo (zavershiv vvod tochkoi i nazhatiem klavishi ENTER):" << endl;
            while(cin.get(Sym)) {
                if(isalnum(Sym)) {
                    search_string.push_back(Sym);
                } else if(TextEditor::EOI == Sym) {
                    break;
                } else {
                    continue;
                }
            }
            if(search_string.empty()) {
                cout << "Poisk po pustoy stroke ne vozmozhen!" << endl;
            } else {
                Node *pv = this->_wordList;
                unsigned int countMatches = 0;
                while(pv) {
                    if(pv->Word == search_string) {
                        countMatches++;
                    }
                    pv = pv->next;
                }
                cout << endl << "Iskomoe vami slovo vstrechaetsya " << countMatches << "raz." << endl;
            }
        };
        void replaceWord(bool replace_all_matches = false) {
            string searched_string;
            string  replace_string;
            char Sym = '~';
            cout << "Vvedite zamenyaemoe slovo (zavershiv vvod tochkoi i nazhatiem klavishi ENTER):" << endl;
            while(cin.get(Sym)) {
                if(isalnum(Sym)) {
                    searched_string.push_back(Sym);
                } else if(TextEditor::EOI == Sym) {
                    break;
                } else {
                    continue;
                }
            }
            Sym = '~';
            cout << "Vvedite slovo-zamenitel' (zavershiv vvod tochkoi i nazhatiem klavishi ENTER):" << endl;
            while(cin.get(Sym)) {
                if(isalnum(Sym)) {
                    replace_string.push_back(Sym);
                } else if(TextEditor::EOI == Sym) {
                    break;
                } else {
                    continue;
                }
            }
            if(searched_string.empty() || replace_string.empty()) {
                cout << "Odno iz vvedennyh vami slov yavlyaetsya pustym, eto protivorechit logike raboty prilozheniya!" << endl;
            } else {
                Node *pv = this->_wordList;
                unsigned int replacesCount = 0;
                while(pv) {
                    if(pv->Word == searched_string) {
                        replacesCount++;
                        pv->Word = replace_string;
                        if(!replace_all_matches) {
                            break;
                        }
                    }
                    pv = pv->next;
                }
                if(0 < replacesCount) {
                    cout << "Zamena slova proshla uspeshno!" << endl;
                } else {
                    cout << "Ne bylo proizvedeno ni odnoj zameny, t.k zamenyaemoe slovo v stroke otsutsvuet!" << endl;
                }
            }
        };
        void insertWord(bool before_temp_word = false){
            cout << "!!!!!" << endl;
            string searched_string;
            string   insert_string;
            char Sym = '~';
            if(before_temp_word) {
                cout << "Vvedite slovo pered kotorym nado vstavit' drugoe (zavershiv vvod tochkoi i nazhatiem klavishi ENTER):" << endl;
            } else {
                cout << "Vvedite slovo posle kotorogo nado vstavit' drugoe (zavershiv vvod tochkoi i nazhatiem klavishi ENTER):" << endl;
            }
            while(cin.get(Sym)) {
                if(isalnum(Sym)) {
                    searched_string.push_back(Sym);
                } else if(TextEditor::EOI == Sym) {
                    break;
                } else {
                    continue;
                }
            }
            Sym = '~';
            //cout << "!!!!!" << endl;
            cout << "Vvedite slovo kotoroe hotite vstavit' (zavershiv vvod tochkoi i nazhatiem klavishi ENTER):" << endl;
            while(cin.get(Sym)) {
                if(isalnum(Sym)) {
                    insert_string.push_back(Sym);
                } else if(TextEditor::EOI == Sym) {
                    break;
                } else {
                    continue;
                }
            }
            //cout << "!!!!!" << endl;
            if(searched_string.empty() || insert_string.empty()) {
                cout << "Odno iz vvedennyh vami slov yavlyaetsya pustym, eto protivorechit logike raboty prilozheniya!" << endl;
            } else {
                //cout << "!!!!!" << endl;
                Node *pv = this->_wordList;
                bool searched_found = false;
                //cout << "pv===" << pv << endl;
                while(pv) {
                    if(pv->Word == searched_string) {
                        searched_found = true;
                        Node *newWord = new Node(insert_string);
                        if(before_temp_word) {
                            newWord->next = pv;
                            Node *oldPrevWord = pv->prev;
                            oldPrevWord->next = newWord;
                            newWord->prev = oldPrevWord;
                            pv->prev = newWord;
                        } else {
                            Node *oldNextWord = pv->next;
                            newWord->next = oldNextWord;
                            oldNextWord->prev = newWord;
                            newWord->prev = pv;
                            pv->next = newWord;
                        }
                        break;
                    }
                    pv = pv->next;
                    cout << "!" << endl;
                }
                if(searched_found) {
                    cout << "Vstavka slova proshla uspeshno!" << endl;
                } else {
                    cout << "Orientirovochnoe slovo ne naideno!" << endl;
                }
            }
        };
        void addWord(bool to_end = false) {
            string add_word;
            char Sym = '~';
            cout << "Vvedite slovo, kotoroe hotite dobavit' (zavershiv vvod tochkoi i nazhatiem klavishi ENTER):" << endl;
            while(cin.get(Sym)) {
                if(isalnum(Sym)) {
                    add_word.push_back(Sym);
                } else if(TextEditor::EOI == Sym) {
                    break;
                } else {
                    continue;
                }
            }
            if(add_word.empty()) {
                cout << "Vy pytaetes' dobavit' slovo predstavlyaenoe pustoi strokoi!" << endl;
            } else {
                if(to_end) {
                    Node *newWord = new Node(add_word);
                    Node *oldWordListEnd = this->_wordListEnd;
                    oldWordListEnd->next = newWord;
                    newWord->prev = oldWordListEnd;
                    this->_wordListEnd = newWord;
                } else {
                    Node *oldFirstElement = this->_wordList;
                    this->_wordList->prev = new Node(add_word);
                    this->_wordList = this->_wordList->prev;
                    this->_wordList->next = oldFirstElement;
                }
                cout << "Dobavlenie elementa proshlo uspeshno!" << endl;
            }
        };
        ~TextEditor() {
            Node *tmp;
            while(this->_wordList) {
                tmp = this->_wordList->next;
                delete this->_wordList;
                this->_wordList = tmp;
            }
        };

    private:
        string _userEnter;
        struct Node {
            string Word;
            Node *prev;
            Node *next;
            Node(string text) {
                this->Word = text;
                this->prev =    0;
                this->next =    0;
            }
        };
        Node *_wordList;
        Node *_wordListEnd;
        void addFirstWord(string fw) {
            this->_wordList    =    new Node(fw);
            this->_wordListEnd = this->_wordList;
        };
};


И код использующий этот класс:
Код

#include "stdafx.h"
#include <iostream>
#include <cctype>
#include <string>
#include "TxtEditor.cpp"
using namespace std;

void main() {
    char inputCtrlSym;
    bool stringInputed = false;
    bool drawLegend = true;
    TextEditor *TxtEditor;
    do {
        if(drawLegend) {
            TextEditor::drawLegend();
            drawLegend = false;
        }
        cout << "Vvedite simvol operacii: ";
        inputCtrlSym = ' ';
        cin.get(inputCtrlSym);
        cin.ignore();
        if('0' == inputCtrlSym && !stringInputed) {
            stringInputed = true;
            TxtEditor = new TextEditor;
        } else if('1' == inputCtrlSym && stringInputed) {
            TxtEditor->searchWord();
        } else if(('2' == inputCtrlSym || '3' == inputCtrlSym) && stringInputed) {
            bool replaceAll = '2' == inputCtrlSym ? false : true;
            TxtEditor->replaceWord(replaceAll);
        } else if(('4' == inputCtrlSym || '5' == inputCtrlSym)&& stringInputed) {
            bool toEnd = '4' == inputCtrlSym ? false : true;
            TxtEditor->addWord(toEnd);
        } else if('6' == inputCtrlSym && stringInputed) {
            cout << "Vstavit' slovo do opredelennogo? (Y/N)" << endl;
            char insParam;
            cin >> insParam;
            bool ins_before = false;
            if(tolower(insParam) == 'y') {
                ins_before = true;
            } else {
                ins_before = false;
            }
            cout << "????" << endl;
            TxtEditor->insertWord(ins_before);
        } else if('7' == inputCtrlSym && stringInputed) {
            //
        } else if('8' == inputCtrlSym && stringInputed) {
            //
        } else if(('!' == inputCtrlSym || '@' == inputCtrlSym) && stringInputed) {
            bool isReverse = '!' == inputCtrlSym ? false : true;
            TxtEditor->printInput(isReverse);
        } else if('#' == inputCtrlSym && stringInputed) {
            TextEditor::drawLegend();
        } else if('9' != inputCtrlSym) {
            cout << "Vy pytaetes' vypolnit' nedopustimoe v dannyi moment deistvie!" << endl;
        }
    } while('9' != inputCtrlSym);
    if(stringInputed) {
        delete TxtEditor;
    }
    int i;
    cout << "Ozhidanie vyhoda iz prilozheniya..." << endl;
    cin >> i;
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)