我创建了一个小型站点线程序,用户可以将自己的站点列表全部指向对方。我没有经验的指针和结构,你会清楚地看到,但任何援助将不胜感激。
我的代码到目前为止已列出了第一个(开始后一个)已被命名的站点。它循环一段时间,当然不能打印空字符串,因此会出现错误。我怎样才能解决这个错误以及我有多愚蠢?
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;
}
从你的代码(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 ;
}
Station *newStation = new Station;
问题是您没有初始化新的struct对象。 new
不会对它返回的内存状态做出任何保证。所以你的newStation-> next可能有任何值,导致它可能使nullptr / NULL检查失败。