双向链表结构 - 覆盖
Doubly Linked List of Structures - Overwriting
所以我试图用 C++ 编写一个程序,对双向链表执行基本操作。我遇到的主要问题是,每次我向列表添加新元素时,我为新元素输入的 id 字段都会覆盖所有其他元素的 id 字段。 id 字段是唯一执行此操作的字段,这让我非常困惑。我相信我的错误可能在于我使用指针的某个地方,因为这是我在 C++ 中使用它们来管理列表的第一个程序(Ada 中的指针对我来说似乎更简单)。我已经 运行 我的程序多次通过 GDB 逐步执行,但似乎仍然无法确定导致问题的原因。这让我相信这可能是我的逻辑错误。
这是我的主要内容:
#include <iostream>
#include "list.h"
#include <string.h> // <string>
using namespace std;
int main (void)
{
int choice, printorder;
char idbuffer[100];
rec r;
do
{
cout << "Enter your choice: 1 - Add, 2 - Delete, 3 - Print, 0 - quit. " <<endl;
cin >> choice;
switch ( choice )
{
case 1: //AddItem
cout << "\nEnter ID ";
cin >> idbuffer;
r.id = idbuffer;
cout << "\nFirst Name ";
cin >> r.firstname;
cout << "\nLast Name ";
cin >> r.lastname;
if ( AddItem ( r ) )
{
cout << "\nSuccess!\n";
}
else
{
cout << "\nItem failed to be added.\n";
}
break;
case 2: //Delete
cout << "\nEnter id: ";
cin >> idbuffer;
if ( DeleteItem ( idbuffer ) )
{
cout << "\nDelete OK.\n";
}
else
{
cout << "\nDelete Failed for: " << idbuffer << endl;
}
break;
case 3: // Print
cout << "Enter order: 0 - Ascending, 1 - Descending. \n";
cin >> printorder;
PrintList (printorder);
break;
case 0: // quit
break;
default: // bad choice
break;
} // end switch
}
while ( choice != 0 );// end do while
} // end main
这是我的文件 list.h:
struct rec
{
char * id;
char firstname[15];
char lastname[15];
rec* prev;
rec* next;
};
int AddItem ( rec r );
int DeleteItem ( char* delid );
void PrintList ( int order );
最后是我文件中的 AddItem 函数 list.cpp:
#include <iostream>
#include "list.h"
#include <string.h>
using namespace std;
rec * first = NULL;
rec * last = NULL;
int AddItem( rec r )
//Return: 1 if a success, 0 if failed.
//No duplicate id's, sort by lastname
{
rec * ptr = NULL;
rec * current;
rec * myStruct = new rec;
myStruct -> id = r.id;
strcpy(myStruct -> firstname, r.firstname);
strcpy(myStruct -> lastname, r.lastname);
ptr = first;
//Check for duplicate id's, currently commented out due to id's being overwritten
//while (ptr)
//{
// if (ptr -> id == myStruct -> id)
// {
// return 0;
// }
// ptr = ptr -> next;
//}
//ptr = first;
if (first == NULL) //Empty
{
first = myStruct; //Inserts node into empty list
last = myStruct;
myStruct -> prev = NULL;
myStruct -> next = NULL;
return 1;
}
else if (myStruct -> lastname > last -> lastname) //Add to end of list
{
last -> next = myStruct;
myStruct -> prev = last;
last = myStruct;
return 1;
}
else if (myStruct -> lastname && myStruct -> lastname < first -> lastname) //Add to beginning of list
{
ptr = first;
first = myStruct;
myStruct -> next = ptr;
ptr -> prev = myStruct;
return 1;
}
else
{
current = first;
while (current)
{
if (myStruct -> lastname > current -> lastname && myStruct -> lastname <= current -> next -> lastname)
{
ptr = current -> next;
current -> next = myStruct;
myStruct -> prev = current;
myStruct -> next = ptr;
ptr -> prev = myStruct;
return 1;
}
else
{
current = current -> next;
}
}
return 0;
}
我确定这段代码中还有其他错误和一些草率的编程,但我计划在解决这个覆盖问题后修复这些错误并使程序 neater/more 高效,因为它也是阻止我测试程序的其他部分。提前致谢,抱歉冗长 post.
Update1: 意识到我需要更改线路后
myStruct -> id = r.id;
到一个字符串拷贝,如:
strcpy(myStruct -> id, r.id);
我现在收到一个分段错误。我想我的指针有些乱七八糟。我回去工作了,感谢迄今为止所有的帮助!
Update2: 经过更多的编辑和更多的错误之后,我的程序可以运行了!我现在正在清理和优化程序。感谢大家的宝贵建议!
所有id对象都有相同的值-idbuffer
的第一个字符的地址。
主要
cin >> idbuffer;
r.id = idbuffer;
^^^^^^^^^
然后在 AddItem
int AddItem( rec r )
//Return: 1 if a success, 0 if failed.
//No duplicate id's, sort by lastname
{
rec * ptr = NULL;
rec * current;
rec * myStruct = new rec;
myStruct -> id = r.id;
^^^^^
//...
您应该动态分配 id
指向的内存,并在那里复制带有 id 的实际字符串。或者您应该将数据成员 id
声明为字符数组。
例如 main
cin >> idbuffer;
r.id = new char[std::strlen( idbuffer ) + 1];
std::strcpy( r.id, idbuffer );
并在 AddItem
rec * myStruct = new rec( r );
更好的方法是使用 std::string
.
类型的对象
所以我试图用 C++ 编写一个程序,对双向链表执行基本操作。我遇到的主要问题是,每次我向列表添加新元素时,我为新元素输入的 id 字段都会覆盖所有其他元素的 id 字段。 id 字段是唯一执行此操作的字段,这让我非常困惑。我相信我的错误可能在于我使用指针的某个地方,因为这是我在 C++ 中使用它们来管理列表的第一个程序(Ada 中的指针对我来说似乎更简单)。我已经 运行 我的程序多次通过 GDB 逐步执行,但似乎仍然无法确定导致问题的原因。这让我相信这可能是我的逻辑错误。
这是我的主要内容:
#include <iostream>
#include "list.h"
#include <string.h> // <string>
using namespace std;
int main (void)
{
int choice, printorder;
char idbuffer[100];
rec r;
do
{
cout << "Enter your choice: 1 - Add, 2 - Delete, 3 - Print, 0 - quit. " <<endl;
cin >> choice;
switch ( choice )
{
case 1: //AddItem
cout << "\nEnter ID ";
cin >> idbuffer;
r.id = idbuffer;
cout << "\nFirst Name ";
cin >> r.firstname;
cout << "\nLast Name ";
cin >> r.lastname;
if ( AddItem ( r ) )
{
cout << "\nSuccess!\n";
}
else
{
cout << "\nItem failed to be added.\n";
}
break;
case 2: //Delete
cout << "\nEnter id: ";
cin >> idbuffer;
if ( DeleteItem ( idbuffer ) )
{
cout << "\nDelete OK.\n";
}
else
{
cout << "\nDelete Failed for: " << idbuffer << endl;
}
break;
case 3: // Print
cout << "Enter order: 0 - Ascending, 1 - Descending. \n";
cin >> printorder;
PrintList (printorder);
break;
case 0: // quit
break;
default: // bad choice
break;
} // end switch
}
while ( choice != 0 );// end do while
} // end main
这是我的文件 list.h:
struct rec
{
char * id;
char firstname[15];
char lastname[15];
rec* prev;
rec* next;
};
int AddItem ( rec r );
int DeleteItem ( char* delid );
void PrintList ( int order );
最后是我文件中的 AddItem 函数 list.cpp:
#include <iostream>
#include "list.h"
#include <string.h>
using namespace std;
rec * first = NULL;
rec * last = NULL;
int AddItem( rec r )
//Return: 1 if a success, 0 if failed.
//No duplicate id's, sort by lastname
{
rec * ptr = NULL;
rec * current;
rec * myStruct = new rec;
myStruct -> id = r.id;
strcpy(myStruct -> firstname, r.firstname);
strcpy(myStruct -> lastname, r.lastname);
ptr = first;
//Check for duplicate id's, currently commented out due to id's being overwritten
//while (ptr)
//{
// if (ptr -> id == myStruct -> id)
// {
// return 0;
// }
// ptr = ptr -> next;
//}
//ptr = first;
if (first == NULL) //Empty
{
first = myStruct; //Inserts node into empty list
last = myStruct;
myStruct -> prev = NULL;
myStruct -> next = NULL;
return 1;
}
else if (myStruct -> lastname > last -> lastname) //Add to end of list
{
last -> next = myStruct;
myStruct -> prev = last;
last = myStruct;
return 1;
}
else if (myStruct -> lastname && myStruct -> lastname < first -> lastname) //Add to beginning of list
{
ptr = first;
first = myStruct;
myStruct -> next = ptr;
ptr -> prev = myStruct;
return 1;
}
else
{
current = first;
while (current)
{
if (myStruct -> lastname > current -> lastname && myStruct -> lastname <= current -> next -> lastname)
{
ptr = current -> next;
current -> next = myStruct;
myStruct -> prev = current;
myStruct -> next = ptr;
ptr -> prev = myStruct;
return 1;
}
else
{
current = current -> next;
}
}
return 0;
}
我确定这段代码中还有其他错误和一些草率的编程,但我计划在解决这个覆盖问题后修复这些错误并使程序 neater/more 高效,因为它也是阻止我测试程序的其他部分。提前致谢,抱歉冗长 post.
Update1: 意识到我需要更改线路后
myStruct -> id = r.id;
到一个字符串拷贝,如:
strcpy(myStruct -> id, r.id);
我现在收到一个分段错误。我想我的指针有些乱七八糟。我回去工作了,感谢迄今为止所有的帮助!
Update2: 经过更多的编辑和更多的错误之后,我的程序可以运行了!我现在正在清理和优化程序。感谢大家的宝贵建议!
所有id对象都有相同的值-idbuffer
的第一个字符的地址。
主要
cin >> idbuffer;
r.id = idbuffer;
^^^^^^^^^
然后在 AddItem
int AddItem( rec r )
//Return: 1 if a success, 0 if failed.
//No duplicate id's, sort by lastname
{
rec * ptr = NULL;
rec * current;
rec * myStruct = new rec;
myStruct -> id = r.id;
^^^^^
//...
您应该动态分配 id
指向的内存,并在那里复制带有 id 的实际字符串。或者您应该将数据成员 id
声明为字符数组。
例如 main
cin >> idbuffer;
r.id = new char[std::strlen( idbuffer ) + 1];
std::strcpy( r.id, idbuffer );
并在 AddItem
rec * myStruct = new rec( r );
更好的方法是使用 std::string
.