【问题标题】:Is my C++ list iterator changing position, or am I doing something wrong?我的 C++ 列表迭代器是在改变位置,还是我做错了什么?
【发布时间】:2014-03-23 19:06:58
【问题描述】:

我正在制作一个 rolodex,并且已经到了可以在列表中添加和搜索“卡片”的地步。但是,在我完成搜索并尝试查看当前的“卡片”(在当前迭代器位置)之后,它给了我一些完全不同的东西。任何想法为什么会发生这种情况(下面的代码摘录)?

Rolodex.h:

#ifndef _ROLODEX_H_
#define _ROLODEX_H_

#include <string>
#include <list>
#include <iterator>
#include <algorithm>

#include "Card.h"   //Card class definition

using namespace std;

class Rolodex
{
    public:
        void add(Card& card);
        Card getCurrentCard();
        bool search(const string&, const string&);
        void show(ostream&);
    private:
        list<Card> rolodex;
        list<Card>::iterator rolodexIt;
};

#endif

Rolodex.cpp:

#include <cctype>
#include <algorithm>
#include <cstring>

#include "Card.h"       //Card class definiton
#include "Rolodex.h"    //Rolodex class definition

using namespace std;

void Rolodex::add(Card& card)
{
    if (rolodex.empty())
    {
        rolodexIt = rolodex.begin();
        rolodex.insert(rolodexIt, card);
        return;
    }

    else
    {    
        rolodexIt = rolodex.begin();
        while (rolodexIt != rolodex.end())
        {
            if (!rolodexIt -> getLastName().compare(card.getLastName()) && !rolodexIt -> getFirstName().compare(card.getFirstName()))
            {
                rolodex.insert(rolodexIt, card);
                return;
            }

            else
            {
                int length;
                int roloLength = rolodexIt -> getLastName().size();
                int userLength = card.getLastName().size();

                if (roloLength < userLength)
                {
                    length = roloLength;
                }

                else
                {
                    length = userLength;
                }

                for (int i = 0; i < length; i++)
                {
                    char rolo = rolodexIt -> getLastName().at(i);
                    char user = card.getLastName().at(i);

                    if (rolo > user)
                    {
                        rolodex.insert(rolodexIt, card);
                        return;
                    }

                    else if (rolo < user)
                    {
                        break;
                    }
                }

                rolodexIt++;
            }
        }

        rolodexIt = rolodex.end();
        rolodex.insert(rolodexIt, card);
    }
}

Card Rolodex::getCurrentCard()
{
    return *rolodexIt;
}

bool Rolodex::search(const string& lastName, const string& firstName)
{
    list<Card>::iterator tempIt = rolodexIt;

    rolodexIt = rolodex.begin();

    while (rolodexIt != rolodex.end())
    {
        if (!rolodexIt -> getLastName().compare(lastName) && !rolodexIt -> getFirstName().compare(firstName))
        {
            return true;
        }

        else
        {
            rolodexIt++;
        }
    }

    cout << endl << "No exact matches found: Displaying closest match." << endl;
    rolodexIt = rolodex.begin();

    while (rolodexIt != rolodex.end())
    {        
        int length;
        int roloLength = rolodexIt -> getLastName().size();
        int userLength = lastName.size();

        if (roloLength < userLength)
        {
            length = roloLength;
        }

        else
        {
            length = userLength;
        }

        for (int i = 0; i < length; i++)
        {
            char rolo = rolodexIt -> getLastName().at(i);
            char user = lastName.at(i);

            if (rolo == user)
            {
                if (roloLength < userLength && i + 1 == roloLength)
                {
                    rolodexIt++;
                    return true;
                }

                else if (roloLength > userLength && i + 1 == userLength)
                {
                    return true;
                }
            }

            else if (rolo > user)
            {
                return true;
            }

            else if (rolo < user)
            {
                break;
            }
        }

        rolodexIt++;
    }

    rolodexIt = tempIt;
    return false;         
}

void Rolodex::show(ostream& os)
{
    list<Card>::iterator tempIt = rolodexIt;

    for (rolodexIt = rolodex.begin(); rolodexIt != rolodex.end(); rolodexIt++)
    {
        rolodexIt -> show(os);
    }

    rolodexIt = tempIt;
}

main.cpp

#include <iostream>
#include <cstring>

#include "Card.h"       //Card class definition
#include "Rolodex.h"    //Rolodex class definition

using namespace std;

void listDex(Rolodex temp)
{
    temp.show(cout);
}

void view(Rolodex temp)
{
    temp.getCurrentCard().show(cout);
}

void search(Rolodex temp)
{
    string lastName;
    string firstName;

    cout << endl << "Enter last and first names for search:" << endl;

    cout << "Last Name: ";
    cin >> lastName;

    cout << "First Name: ";
    cin >> firstName;

    if (temp.search(lastName, firstName))
    {
        view(temp);
    }
}

int quit()
{
    cout << endl << "Program ended." << endl;
    return 0;
}

int main(void)
{
    int status = 1;

    Rolodex testData;

    Card card[10];

    card[0].setFirstName("Tony");
    card[0].setLastName("Hansen");
    card[0].setOccupation("Writer");
    card[0].setAddress("12 E. St. NY, NY 33333");
    card[0].setPhoneNumber("555-9999");

    card[1].setFirstName("Jon");
    card[1].setLastName("Smyth");
    card[1].setOccupation("Computer Hardware");
    card[1].setAddress("CMU Computer Services\nPittsburgh, PA");
    card[1].setPhoneNumber("555-1324");

    for (int i = 0; i < 10; i++)
    {
        testData.add(card[i]);
    }

    listDex(testData);
    search(testData);
    view(testData);
    quit();
}

我试图删减代码,但它看起来仍然很长......对此感到抱歉。 =/

基本上,我遇到的问题是我打电话时

view(testData);

它返回的内容与我刚刚查看的内容完全不同

search(testData);

感谢任何帮助、建议和建设性的批评。感谢您的宝贵时间!

【问题讨论】:

    标签: c++ list iterator


    【解决方案1】:

    view()search() 正在按值传递 Rolodex 对象。这意味着第一次调用search() 时会生成一个新对象,并且副本的迭代器在search() 中被修改。这些修改并未对稍后传递给view()testData Rolodex 对象进行,因此无法按预期工作。

    您应该通过引用或指针传递它们。

    还请注意,您正在访问card[0..9],即使您只显式初始化了前两个。如果Card 构造函数正确初始化对象,这可能仍然可以。

    【讨论】:

    • 哦,哇...因为在传入时将 Rolodex 对象命名为“temp”,我似乎忘记了这个词的含义。现在修复它。谢谢! :)
    • 我在实际代码中添加了所有 10 张卡片......在我的问题中为了简洁起见将它们剪掉,哈哈。再次感谢!
    猜你喜欢
    • 2011-05-02
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2017-09-28
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多