而使用 getline() 的循环没有爆发

while loop using getline() not breaking out

本文关键字:循环 爆发 getline      更新时间:2023-10-16

所以我有这部分代码,它工作得很好。然后我添加了一些行(它下面的代码),现在它在执行时崩溃。从我所做的测试来看,它似乎卡在了while循环中。我是新手,我不明白这些变化如何影响

编辑:程序编译没有错误。执行时出现以下消息:此应用程序已请求运行时以异常方式终止它。现在它不会让我使用调试器...(我正在使用开发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 l’espion(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;
}

您的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 l’espion(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 l’espion(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 在 #include <forward_list> 中添加了一个 std::forward_list 类。