цикл while с использованием getline () не прерывается

0

Так что у меня была эта часть кода, которая работала нормально. Затем я добавил несколько строк (код ниже), и теперь он сбой при выполнении. Из тестов, которые я сделал, он, кажется, застрял в цикле while. Я новичок, и я не вижу, как эти изменения повлияли

EDIT: программа компилируется без ошибок. Это сообщение появляется во время исполнения: это приложение запросило Runtime для его необычного завершения. И теперь это не позволит мне использовать отладчик... (я использую Dev C++)

int main() {
    char fileName[] = "espion.txt";
    std:: string infoEspion;
    Espion *cur = 0, *first = 0, *last = 0, *add = 0;
    std :: ifstream readFile;

    readFile.open(fileName, std::ios::in);

    if(!readFile.is_open())
        exit(EXIT_FAILURE);

    while(std::getline(readFile, infoEspion)) {
        if(first == NULL){ //head
            add = new Espion;
            add -> name = infoEspion.substr(0,30);
            add -> next = NULL;
            first = add;
            cur = add;
            last = add;
        } else if(findName(first, infoEspion.substr(0,30)) == NULL ) {
            // adding only if not on the list already
            add = new Espion;
            add -> name = infoEspion.substr(0,30);
            add -> next = NULL;
            cur -> next = add;
            last = add;
            cur = add;
        }
    }
    printList(first);
    printList(sortAlpha(first));
    readFile.close();

    system("pause");
    return 0;
}

НОВЫЙ КОД

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cerrno>

struct Pays
{
    std:: string name; /* nom du pays */
    Pays *next; /* pointeur sur le prochain pays */
};

struct Espion
{
    std:: string name; /* nom de lespion(ne) */
    Espion *next; /* pointeur sur le prochain espion */
    Pays *begListPays; /* tête de liste des pays visités */
    Pays *endListPays;
};

Espion *findName(Espion* ptr, std::string nameToCompare)// returns pointer or NULL
{
    while (ptr)
    {
         if(ptr->nom.compare(nameToCompare) == 0)
              return ptr;
         ptr = ptr->next;
    }
    ptr = NULL;
    return ptr;
}

int main() {
    char fileName[] = "espion.txt";
    std:: string infoEspion;
    Espion *cur = 0, *first = 0, *last = 0, *add = 0, *curP = 0;
    Pays *firstP = 0, *lastP = 0, *addP = 0;
    std :: ifstream readFile;

    readFile.open(fileName, std::ios::in);

    if(!readFile.is_open())
        exit(EXIT_FAILURE);

    while(std::getline(readFile, infoEspion)) {
        if(first == NULL){ //head
            add = new Espion;
            add -> name = infoEspion.substr(0,30);
            add -> next = NULL;
            first = add;
            cur = add;
            last = add;
            addP = new Pays;
            addP-> name = infoEspion.substr(30,20);
            addP-> next = NULL;
            add-> begListPays = addP;
            add-> endListPays = addP;
            //changes up to here run OK!
        } else if(findName(first, infoEspion.substr(0,30)) == NULL ) {
            // adding only if not on the list already
            add = new Espion;
            add -> name = infoEspion.substr(0,30);
            add -> next = NULL;
            cur -> next = add;
            last = add;
            cur = add;
            addP = new Pays;
            addP->name = infoEspion.substr(30,20);
            addP->next = NULL;
            add->begListPays = addP;
            add->endListPays = addP;
        } else {
            addP = new Pays;
            addP-> name = infoEspion.substr(30,20);
            addP-> next = NULL;
            findName(first, infoEspion.substr(0,30))->endListPays->next = addP;
            findName(first, infoEspion.substr(0,30))->endListPays = addP;
        }
    }
    printList(first);
    printList(sortAlpha(first));
    readFile.close();

    system("pause");
    return 0;
}
  • 0
    Если вы скажете, где произошла ошибка, будет полезно точное сообщение об ошибке. Также где определено findName?
  • 0
    Я отредактировал свой пост .. И я почти уверен, что ошибка возникает в то время как со второй, если и ничего не распечатывается, прежде чем он падает
Теги:

1 ответ

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

Ваш while цикл не принимая во внимание, что последняя строка будет пустой, если файл заканчивается разрывом строки, таким образом, substr(30,20) вызывают исключение.

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

Попробуй это:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cerrno>
#include <string>

struct Pays
{
    std::string name; /* nom du pays */
    Pays *next; /* pointeur sur le prochain pays */
};

struct Espion
{
    std::string name; /* nom de lespion(ne) */
    Espion *next; /* pointeur sur le prochain espion */
    Pays *begListPays; /* tête de liste des pays visités */
    Pays *endListPays;
};

Espion* findName(Espion* ptr, std::string nameToCompare)// returns pointer or NULL
{
    while (ptr)
    {
        if(ptr->name.compare(nameToCompare) == 0)
            return ptr;
        ptr = ptr->next;
    }
    return NULL;
}

int main()
{
    char fileName[] = "espion.txt";
    std::string infoEspion, espionName, paysName;
    Espion *first = 0, *last = 0, *add;
    Pays *addP;
    std::ifstream readFile;

    readFile.open(fileName, std::ios::in);
    if (!readFile.is_open())
        exit(EXIT_FAILURE);

    while (std::getline(readFile, infoEspion))
    {
        if (infoEspion.empty())
            continue;

        espionName = infoEspion.substr(0,30);
        paysName = infoEspion.substr(30,20);

        add = findName(first, espionName);
        if (!add)
        {
            add = new Espion;
            add->name = espionName;
            add->next = NULL;
            add->begListPays = NULL;
            add->endListPays = NULL;
            if (!first) first = add;
            if (last) last->next = add;
            last = add;
        }

        addP = new Pays;
        addP->name = paysName;
        addP->next = NULL;
        if (!add->begListPays) add->begListPays = addP;
        if (add->endListPays) add->endListPays->next = addP;
        add->endListPays = addP;
    }

    printList(first);
    printList(sortAlpha(first));

    readFile.close();

    system("pause");
    return 0;
}

С учетом сказанного вам следует воспользоваться функциями C++, которые больше управляют логикой для вас:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cerrno>
#include <string>
#include <list>
#include <algorithm>

struct Pays
{
    std::string name; /* nom du pays */
};

struct Espion
{
    std::string name; /* nom de lespion(ne) */
    std::list<Pays> ListPays; /* tête de liste des pays visités */

    bool operator<(const Espion& rhs) const
    {
        return (name < rhs.name);
    }
};

struct isEspionName
{
    std::string _name;
    isEspionName(const std::string &nameToCompare) : _name(nameToCompare) {}

    bool operator()(const Espion& e) const
    {
        return (e.name == _name);
    }
};

int main()
{
    char fileName[] = "espion.txt";
    std::string infoEspion, espionName, paysName;
    std::list<Espion> ListEspion;
    Espion *e;
    std::ifstream readFile;

    readFile.open(fileName, std::ios::in);
    if (!readFile.is_open())
        exit(EXIT_FAILURE);

    while (std::getline(readFile, infoEspion))
    {
        if (infoEspion.empty())
            continue;

        espionName = infoEspion.substr(0,30);
        paysName = infoEspion.substr(30,20);

        std::list<Espion>::iterator iter = std::find_if(ListEspion.begin(), ListEspion.end(), isEspionName(espionName));
        if (iter != ListEspion.end())
        {
            e = &(*iter);
        }
        else
        {
            Espion addE;
            addE.name = espionName;
            ListEspion.push_back(addE);
            e = &(ListEspion.back());
        }

        Pays addP;
        addP.name = paysName;
        e->ListPays.push_back(addP);
    }

    readFile.close();

    printList(ListEspion);
    ListEspion.sort();
    printList(ListEspion);

    system("pause");
    return 0;
}

std::list реализуется как двойной список. Если вам действительно нужен односвязный список, C++ 11 добавил класс std::forward_list в #include <forward_list>.

  • 0
    (e.name.compare(_name) == 0) почему бы не e.name == _name
  • 0
    Потому что исходный код использовал compare() а я его не менял.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню