c链表中head不断变化
Head constantly changing in c linked list
我正在尝试用 C 实现一个简单的链表,但似乎没有正确添加第一个元素。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
typedef struct person{
int phoneNumber;
char* name;
struct person *nextPers;
}person;
person* firstPerson=NULL;
person* lastPerson=NULL;
void addPerson (person* _person){
/*Adds a new person to the linked list after the last one added
*/
if (firstPerson!=NULL){
fprintf(stderr,"DEBUG(addPerson): First person is %s \n",firstPerson->name);
fprintf(stderr,"DEBUG (addPerson): Last Person is (before adding the new one) %s \n",lastPerson->name);}
fprintf(stderr,"DEBUG: Adding person %s \n",_person->name);
_person->nextPers= NULL;
if (firstPerson==NULL){
firstPerson = _person;
lastPerson= _person;
fprintf(stderr,"DEBUG: The head of the list is %s \n",firstPerson->name);
}else{
fprintf(stderr,"DEBUG: Last person (before adding the new one) %s \n",lastPerson->name);
fprintf(stderr,"DEBUG (addPerson):Adding to the list %s \n",_person->name);
lastPerson->nextPers =_person;
lastPerson=_person;
fprintf(stderr,"DEBUG: Last person %s \n",lastPerson->name);
}
}
int main(int argc, char* argv[]){
char line[80],name[80];
int number;
setvbuf(stdout,(char*)malloc(sizeof(char)*80),_IOLBF,80);
setvbuf(stdin,(char*)malloc(sizeof(char)*80),_IOLBF,80);
for(;fgets(line,80,stdin);){
if(!strcmp(line,"Finish\n"))
break;
sscanf(line,"%[^:]: %d",name,&number);
/* Stores the person introduced from stdin as Name:phone */
if(firstPerson!=NULL){
fprintf(stderr,"DEBUG (Before storing new data aparently): First person is %s \n",firstPerson>name);
}
person * newPerson= malloc(sizeof(person));
newPerson->phoneNumber = number;
newPerson->name = name;
fprintf(stderr,"DEBUG: Adding person %s \n",newPerson->name);
fprintf(stderr,"DEBUG: phone number %d \n",newPerson->phoneNumber);
addPerson(newPerson);
fprintf(stderr,"DEBUG: There is a new person on the list\n");
}
}
预期输出为:
Harvey:12345
DEBUG: Adding person Harvey
DEBUG: phone number 12345
DEBUG: Adding person Harvey
DEBUG: The head of the list is Harvey
DEBUG: There is a new person on the list
Adam:23456
DEBUG (Before storing new data aparently): First person is Harvey
DEBUG: Adding person Adam
DEBUG: phone number 23456
DEBUG(addPerson): First person is Harvey
DEBUG (addPerson): Last Person is (before adding the new one) Harvey
DEBUG: Adding person Adam
DEBUG: Last person (before adding the new one) Harvey
DEBUG (addPerson):Adding to the list Adam
DEBUG: Last person Adam
DEBUG: There is a new person on the list
但是,输出是:
Harvey:12345
DEBUG: Adding person Harvey
DEBUG: phone number 12345
DEBUG: Adding person Harvey
DEBUG: The head of the list is Harvey
DEBUG: There is a new person on the list
Adam:23456
DEBUG (Before storing new data aparently): First person is (null) //Wrong, its Harvey
DEBUG: Adding person Adam
DEBUG: phone number 23456
DEBUG(addPerson): First person is Adam //Wrong, its Harvey
DEBUG (addPerson): Last Person is (before adding the new one) Adam //Wrong, its Harvey
DEBUG: Adding person Adam
DEBUG: Last person (before adding the new one) Adam //Wrong its Harvey
DEBUG (addPerson):Adding to the list Adam
DEBUG: Last person Adam
DEBUG: There is a new person on the list
总结一下,主要的思路是得到一个链表就是:Harvey->Adam->(next) 但是不知道哪里出错了
您犯了一些错误:
struct proceso *nextPers;
这毫无意义,改为
person *nextPers;
然后保存在你的结构中的名字指向 name[80](main() 中的 var),所以每次你的这个 var 改变,你的结构中的那个也会改变。您必须将其复制到您的结构中;
memcpy(newPerson->name, name, 80);
并将您的结构更改为:
typedef struct person{
int phoneNumber;
char name[80];
struct person *nextPers;
}person;
还记得在完成后释放列表中的所有节点
你代码的链表部分是正确的,我知道这会让你抓狂。您的代码中还有一些其他错误,与链表无关。
fprintf(stderr,"DEBUG (Before storing new data aparently): First person is %s \n",firstPerson>name);
看到你写的是 firstPerson>name 而不是 firstPerson->name,这是在进行布尔比较并返回零 - 这就是你在那里有 "null" 的原因。
第二个错误在这里:
newPerson->phoneNumber = number;
newPerson->name = name
您正在将电话号码设置为姓名和号码数组的 指针。所以当你在这里打印第二张时:
DEBUG (addPerson): Last Person is (before adding the new one) Adam //Wrong, its Harvey
它实际上是在检索正确的值 - 因为您将 Harvey 覆盖到 Adam。
修复很简单:将字符串复制到 newPerson 而不是将其指向姓名。
newPerson->name = malloc(sizeof(char) * strlen(name) + 1);
strcpy(newPerson->name, name);
这应该可以解决您的问题。
我正在尝试用 C 实现一个简单的链表,但似乎没有正确添加第一个元素。 这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
typedef struct person{
int phoneNumber;
char* name;
struct person *nextPers;
}person;
person* firstPerson=NULL;
person* lastPerson=NULL;
void addPerson (person* _person){
/*Adds a new person to the linked list after the last one added
*/
if (firstPerson!=NULL){
fprintf(stderr,"DEBUG(addPerson): First person is %s \n",firstPerson->name);
fprintf(stderr,"DEBUG (addPerson): Last Person is (before adding the new one) %s \n",lastPerson->name);}
fprintf(stderr,"DEBUG: Adding person %s \n",_person->name);
_person->nextPers= NULL;
if (firstPerson==NULL){
firstPerson = _person;
lastPerson= _person;
fprintf(stderr,"DEBUG: The head of the list is %s \n",firstPerson->name);
}else{
fprintf(stderr,"DEBUG: Last person (before adding the new one) %s \n",lastPerson->name);
fprintf(stderr,"DEBUG (addPerson):Adding to the list %s \n",_person->name);
lastPerson->nextPers =_person;
lastPerson=_person;
fprintf(stderr,"DEBUG: Last person %s \n",lastPerson->name);
}
}
int main(int argc, char* argv[]){
char line[80],name[80];
int number;
setvbuf(stdout,(char*)malloc(sizeof(char)*80),_IOLBF,80);
setvbuf(stdin,(char*)malloc(sizeof(char)*80),_IOLBF,80);
for(;fgets(line,80,stdin);){
if(!strcmp(line,"Finish\n"))
break;
sscanf(line,"%[^:]: %d",name,&number);
/* Stores the person introduced from stdin as Name:phone */
if(firstPerson!=NULL){
fprintf(stderr,"DEBUG (Before storing new data aparently): First person is %s \n",firstPerson>name);
}
person * newPerson= malloc(sizeof(person));
newPerson->phoneNumber = number;
newPerson->name = name;
fprintf(stderr,"DEBUG: Adding person %s \n",newPerson->name);
fprintf(stderr,"DEBUG: phone number %d \n",newPerson->phoneNumber);
addPerson(newPerson);
fprintf(stderr,"DEBUG: There is a new person on the list\n");
}
}
预期输出为:
Harvey:12345
DEBUG: Adding person Harvey
DEBUG: phone number 12345
DEBUG: Adding person Harvey
DEBUG: The head of the list is Harvey
DEBUG: There is a new person on the list
Adam:23456
DEBUG (Before storing new data aparently): First person is Harvey
DEBUG: Adding person Adam
DEBUG: phone number 23456
DEBUG(addPerson): First person is Harvey
DEBUG (addPerson): Last Person is (before adding the new one) Harvey
DEBUG: Adding person Adam
DEBUG: Last person (before adding the new one) Harvey
DEBUG (addPerson):Adding to the list Adam
DEBUG: Last person Adam
DEBUG: There is a new person on the list
但是,输出是:
Harvey:12345
DEBUG: Adding person Harvey
DEBUG: phone number 12345
DEBUG: Adding person Harvey
DEBUG: The head of the list is Harvey
DEBUG: There is a new person on the list
Adam:23456
DEBUG (Before storing new data aparently): First person is (null) //Wrong, its Harvey
DEBUG: Adding person Adam
DEBUG: phone number 23456
DEBUG(addPerson): First person is Adam //Wrong, its Harvey
DEBUG (addPerson): Last Person is (before adding the new one) Adam //Wrong, its Harvey
DEBUG: Adding person Adam
DEBUG: Last person (before adding the new one) Adam //Wrong its Harvey
DEBUG (addPerson):Adding to the list Adam
DEBUG: Last person Adam
DEBUG: There is a new person on the list
总结一下,主要的思路是得到一个链表就是:Harvey->Adam->(next) 但是不知道哪里出错了
您犯了一些错误:
struct proceso *nextPers;
这毫无意义,改为
person *nextPers;
然后保存在你的结构中的名字指向 name[80](main() 中的 var),所以每次你的这个 var 改变,你的结构中的那个也会改变。您必须将其复制到您的结构中;
memcpy(newPerson->name, name, 80);
并将您的结构更改为:
typedef struct person{
int phoneNumber;
char name[80];
struct person *nextPers;
}person;
还记得在完成后释放列表中的所有节点
你代码的链表部分是正确的,我知道这会让你抓狂。您的代码中还有一些其他错误,与链表无关。
fprintf(stderr,"DEBUG (Before storing new data aparently): First person is %s \n",firstPerson>name);
看到你写的是 firstPerson>name 而不是 firstPerson->name,这是在进行布尔比较并返回零 - 这就是你在那里有 "null" 的原因。
第二个错误在这里:
newPerson->phoneNumber = number;
newPerson->name = name
您正在将电话号码设置为姓名和号码数组的 指针。所以当你在这里打印第二张时:
DEBUG (addPerson): Last Person is (before adding the new one) Adam //Wrong, its Harvey
它实际上是在检索正确的值 - 因为您将 Harvey 覆盖到 Adam。
修复很简单:将字符串复制到 newPerson 而不是将其指向姓名。
newPerson->name = malloc(sizeof(char) * strlen(name) + 1);
strcpy(newPerson->name, name);
这应该可以解决您的问题。