虽然循环循环第三次虽然它在我眼中的条件不符合,但因此打印出一个空字符串

问题描述 投票:0回答:2

我创建了一个小型站点线程序,用户可以将自己的站点列表全部指向对方。我没有经验的指针和结构,你会清楚地看到,但任何援助将不胜感激。

我的代码到目前为止已列出了第一个(开始后一个)已被命名的站点。它循环一段时间,当然不能打印空字符串,因此会出现错误。我怎样才能解决这个错误以及我有多愚蠢?

using namespace std;

struct Station
{
    string name;
    Station *next;
};


int main()
{
    string startName = "Start";

    Station *start = new Station;   
    start->name = startName;
    start->next = NULL; 

    Station *pointer = NULL;

    char addkey = 'n';
    char response;
    bool adding = true;

    cout << "Enter 'n' to add a New Station" << endl;
    cin >> response;

    if (response == addkey)
    {
        do
        {
            char addAgain;
            string newName;
            string fromStation;

            Station *beforePointer = pointer;

            cout << "\nEnter New Station Name" << endl;
            cin >> newName;

            pointer = start;

            cout << "\nStation List:" << endl << start->name << endl;   
            do
            {
                beforePointer = pointer;
                cout << beforePointer->name << endl; // Issue running this line the second run of the code, third run of the do-while loop. String at start->next->next->name; a nullptr
                pointer = pointer->next; 
            }
            while (beforePointer->next != nullptr);

            cout << "\nEnter Station it is from (top to bottom)" << endl;
            cin >> fromStation;

            pointer = start->next;

            bool pointed;
            pointed = false;

            if (start->name == fromStation)
            {
                string placeholdString;
                Station *placeholdPointer;

                Station *newStation = new Station;

                if (start->next != NULL) // Hasn't been tested as of yet
                {
                    placeholdString = start->next->name;
                    placeholdPointer = start->next;
                    start->next = newStation;
                    start->next->name = newName;
                    start->next->next = placeholdPointer;
                    start->next->name = placeholdString;
                    pointed = true;
                }
                else
                {
                    start->next = newStation;
                    start->next->name = newName;
                    pointed = true;
                }

            }
            else
            {
                pointer = start->next;

                do
                {
                    if (pointer->name == fromStation)
                    {
                        string placeholdString;
                        Station *placeholdPointer;

                        Station *newStation = new Station;

                        if (pointer->next != NULL) // Hasn't been tested as of yet
                        {
                            placeholdString = pointer->next->name;
                            placeholdPointer = pointer->next;
                            pointer->next = newStation;
                            pointer->next->name = newName;
                            pointer->next->next = placeholdPointer;
                            pointer->next->name = placeholdString;
                            pointed = true;
                        }
                        else
                        {
                            pointer->next = newStation;
                            pointer->next->name = newName;
                            pointed = true;
                        }       
                    }
                    if (pointed == false)
                    {
                        pointer = pointer->next;
                    }
                }
                while (pointer->next != NULL);
            }


            cout << "\nWould you like to add more?" << endl << "Enter 'n' again" << endl;
            cin >> addAgain;

            if (addAgain != addkey)
            {
                adding = false;
            }
            else if (addAgain == addkey)
            {
                adding = true;
            }
        } 
        while (adding == true);
    }

    system("pause");
    return 0;
}
c++ pointers struct
2个回答
0
投票

从你的代码(do-while循环):

    /* Add #include <assert.h> at top of file */

    // Run #1
    assert( pointer != NULL ) ;
    beforepointer  = pointer ; // beforepointer == pointer == start

    assert( beforepointer != NULL ) ;
    assert( beforepointer->name != NULL ) ;

    cout << beforepointer->name << endl ; // Will print 'Start'
    pointer = pointer->next ; // pointer->next == start->next == NULL
    assert( pointer != NULL ) ; // SHOULD FAIL HERE (will abort)

    // (pointer is now NULL)

    // Run #2
    beforepointer = pointer ; // beforepointer == pointer == NULL
    assert( beforepointer != NULL ) ; // This would fail too
    cout << beforepointer(== NULL)->name << endl ; // *** Segmentation violation!
    ...

您不再指向第二次运行时有效的任何内容,beforepointer为NULL。

打印出列表的更好方法是:

beforepointer = pointer ;
assert( beforepointer != NULL ) ;

while ( beforepointer != NULL ) {
    assert( beforepointer->name != NULL ) ;

    cout << beforepointer->name << endl ;
    beforepointer = beforepointer->next;
}

编辑:释放您的代码示例,并使用标准的c ++库,您可以如下所示简化它(使用向量):

/**
 * Wrapper function to prompt user for input
 */
istream & queryUser( const string & prompt, string & answer ) {
  cout << prompt << ' ' << flush ;
  getline( cin, answer ) ;
  return cin;
}

/** Always useful emptiness test function */
bool isBlankOrEmpty( const string & s ) {
    return s.empty() || s.find_first_not_of( " \t") == string::npos ;
}
/**
 * The big main
 */
int main() {
  vector<string> stations ; // list of station names

  // ... Accept user input as long as input is entered
  string newStationName ;
  while( queryUser( "Enter new station name (or hit ENTER to exit)", newStationName ) ) {

    // ... Quit if the line is empty
    if ( isBlankOrEmpty( newStationName ) ) {
        break ;
    }

    // ... Locate insertion point
    vector<string>::iterator insertionPoint = stations.end() ; // append by default

    // ... Have user specify where to insert the new station (if there is such an option)
    if ( stations.size() > 1 ) {

        // ... Where to insert?
        string fromStation ;
        if ( queryUser("Enter station it is from (top to bottom)", fromStation) && ! isBlankOrEmpty( fromStation ) ) {
            vector<string>::iterator it = std::find( stations.begin(), stations.end(), fromStation ) ;
            if ( it != stations.end() ) {
                insertionPoint = ++it ; // move to position after the fromStation
            }
        }
    }

    // ... Insert the new station name
    stations.insert( insertionPoint, newStationName ) ;

    cout << "Your station list:" << endl ;
    for ( auto & stationName : stations ) {
        cout << stationName << endl ;
    }
  }

  return 0 ;
}

0
投票
                        Station *newStation = new Station;

问题是您没有初始化新的struct对象。 new不会对它返回的内存状态做出任何保证。所以你的newStation-> next可能有任何值,导致它可能使nullptr / NULL检查失败。

© www.soinside.com 2019 - 2024. All rights reserved.