首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在C中显示链接列表?

如何在C中显示链接列表?
EN

Stack Overflow用户
提问于 2022-10-25 11:02:47
回答 1查看 65关注 0票数 1
代码语言:javascript
复制
#include <stdio.h>
#include <malloc.h>
struct node
{
    int ID;
    char Name;
    char Pos;
    struct node*next;
};

struct node *start = NULL;
struct node *createList(struct node*);
struct node *displayList(struct node *);

int main()
{
    start=createList(start);
    start = displayList(start);
    return 0;
}

struct node *createList(struct node *start)

{
    struct node *new_node, *ptr;
    int EmpID;
    char EmpName;
    char EmpPos;
    int choice;
    printf("\n Enter the Employee's ID: ");
    scanf("%d", &EmpID);
    printf("\n Enter the Employee's Name: ");
    scanf("%s", &EmpName);
    printf("\n Enter the Employee's Position: ");
    scanf("%s", &EmpPos);
    printf("\n Do you want to add more Employees [Press Any Number Key if 'yes', Press 1 for 'No']: ");
    scanf("%d", &choice);
    while (choice != 1)
    {
        new_node = (struct node *) malloc(sizeof(struct node));
        new_node ->ID=EmpID;
        new_node ->Name =EmpName;
        new_node ->Pos =EmpPos;
        if (start==NULL)
        {
            new_node -> next= NULL;
            start = new_node;
        }
        else
        {
            ptr=start;
            while(ptr->next != NULL)
            {
                 ptr = ptr->next;
            }
            ptr->next = new_node;
            new_node -> next =NULL;

        }
        printf("\n Enter the Employee's ID: ");
        scanf("%d", &EmpID);
        printf("\n Enter the Employee's Name: ");
        scanf("%s", &EmpName);
        printf("\n Enter the Employee's Position: ");
        scanf("%s", &EmpPos);
        printf("\n Do you want to add more Employees [Press Any Number Key if 'yes', Press 1 for 'No']: ");
        scanf("%d", &choice);
    }
    return start;
};

struct node *displayList(struct node *start)
{
    struct node *ptr;
    ptr = start;
    while(ptr !=NULL)
    {
        printf("\t\n Employee's ID: ","%d, ", ptr->ID);
         ptr = ptr->next;
        printf("\t\n Employee's Name: ","%s, ", ptr->Name);
         ptr = ptr->next;
        printf("\t\n Employee's Position: ","%s, ", ptr->Pos);
        ptr = ptr->next;
    }
};

即使没有错误,我的代码也不会显示链接。如何显示?我的预期输出应该是这样的:

输入员工ID: 10

输入员工姓名: Lisa

输入员工职位:首席执行官

是否要添加更多员工按任意数字键(如果‘是’),按1表示'No':5

输入员工ID: 9

输入员工姓名: Rowena

输入员工职位:首席运营官

是否要添加更多员工按任意数字键(如果“是”),按1表示“否”:1

雇员身份证: 10,9

雇员姓名: Lisa,Rowena

雇员职位:首席执行官,首席运营官

当我按1时,我的代码没有显示任何内容。

EN

回答 1

Stack Overflow用户

发布于 2022-10-25 13:08:09

眼前的问题:

代码语言:javascript
复制
struct node
{
    int ID;
    char Name;        // Can only store *single* characters
    char Pos;         // not strings
    struct node*next;
};

按照定义,NamePos只能存储单个字符,而不能存储字符串--您必须将这些字符定义为char数组

代码语言:javascript
复制
#define MAX_NAME_LEN 20 // or however long a name can be
#define MAX_POS_LEN  20 // or however long a pos can be

struct node {
  int ID;
  char Name[MAX_NAME_LEN + 1]; // +1 for string terminator
  char Pos[MAX_POS_LEN + 1];  
  struct node *next;
};

或者,您必须将它们定义为指向char的指针

代码语言:javascript
复制
struct node {
  int ID;
  char *Name;
  char *Pos;
  struct node *next;
};

并在创建节点时分别为它们分配内存:

代码语言:javascript
复制
// read EmpID, EmpName, EmpPos
...
struct node *n = malloc( sizeof *n );
if ( n )
{
  n->Name = calloc( strlen( EmpName) + 1, sizeof *n->Name );
  if ( n->Name )
     strcpy( n->Name, EmpName );
  else
     // handle allocation failure

  n->Pos  = calloc( strlen( EmpPos ) + 1, sizeof *n->Pos );
  if ( n->Pos )
     strcpy( n->Pos, EmpPos );
  else
     // handle allocation failure
} 

输入函数中的EmpNameEmpPos也有相同的问题:

代码语言:javascript
复制
char EmpName;  // EmpName can only store a *single* character
char EmpPos;   // same with EmpPos
...
scanf( "%s", &EmpName );
...
scanf( "%s", &EmpPos );

这将不像您预期的那样工作--如果键入像"Smith" for EmpName这样的输入,'S'将被保存到EmpName中,其余的字符将被写入EmpName之外的内存,覆盖其他数据。

对于输入,绝对需要将EmpNameEmpPos声明为char数组。

代码语言:javascript
复制
char EmpName[MAX_NAME_LENGTH+1];
char EmpPos[MAX_POS_LENGTH+1];

如果他们需要能够存储空间(比如"John Smith"),那么您就不能在%s中使用scanf --要么使用%[说明符,比如

代码语言:javascript
复制
scanf( "%[^\n]", EmpName ); // read everything up to the newline
//              ^
//              +---------- note no & operator here

或者,更好的是,完全抛弃scanf,转而使用fgets

代码语言:javascript
复制
if ( fgets( EmpName, sizeof EmpName, stdin ) )
  // process EmpName
else
  // input error

在您的displayList函数中,在打印每个元素之后,将推进节点指针:

代码语言:javascript
复制
while(ptr !=NULL)
{
    printf("\t\n Employee's ID: ","%d, ", ptr->ID);
     ptr = ptr->next;
    printf("\t\n Employee's Name: ","%s, ", ptr->Name);
     ptr = ptr->next;
    printf("\t\n Employee's Position: ","%s, ", ptr->Pos);
    ptr = ptr->next;
}

IOW,您打印的是第一个节点的ID,然后是第二个节点的Name,然后是第三个节点的Pos。相反,它应该是:

代码语言:javascript
复制
while(ptr !=NULL)
{
    printf("\t\n Employee's ID: ","%d, ", ptr->ID);
    printf("\t\n Employee's Name: ","%s, ", ptr->Name);
    printf("\t\n Employee's Position: ","%s, ", ptr->Pos);
    ptr = ptr->next;
}

我还认为您有您的\t\n向后-您将打印一个选项卡,然后是一个换行符,所以每个项目将打印在一行的开头。如果这是您想要的,那么您可以完全放弃\t,它并没有真正添加任何东西。如果您希望每一项都由一个制表符插入,则需要反转它们- \n\t

最好将I/O函数编写为在单个节点上操作,而不是整个列表:

代码语言:javascript
复制
void displayNode( struct node *n )
{
  printf( "\tEmployee ID:       %d\n", n->ID );
  printf( "\tEmployee Name:     %s\n", n->Name );
  printf( "\tEmployee Position: %s\n", n->Pos );
}

并从迭代列表的函数中调用它:

代码语言:javascript
复制
void displayList( struct node *head )
{
  for ( struct node *cur = head; cur != NULL; cur = cur->next )
    displayNode( cur );
}

同样,将输入、节点创建和节点插入拆分为单独的函数:

代码语言:javascript
复制
struct node *head = NULL;

int EmpId;
char EmpName[MAX_NAME_LEN + 1];
char EmpPos[MAX_POS_LEN + 1];

while ( !done )
{
  if ( getNodeData( &EmpId, EmpName, sizeof EmpName, EmpPos, sizeof EmpPos ) )
  {
    struct node *n = createNode( EmpId, EmpName, EmpPos );
    if ( n )
    {
      insertList( &head, n );
    }
    else
    {
      // handle allocation error
      done = true;
    }
  }
  else
  {
    // handle input error
    done = true;
  }

  if ( !done )
  {
    fputs( "Add another node? [Y/N]: ", stdout );
    int c = getchar();
    done = toupper( c ) == 'Y';
  }
}

在那里getNodeData看起来像

代码语言:javascript
复制
bool getNodeData( int *id, char *name, size_t nameSize, char *pos, size_t posSize )
{
  fputs( "Enter employee ID: ", stdout );
  if ( scanf( "%d", id ) != 1 )
  {
    fputs( "Error reading emp ID\n", stderr );
    return false;
  }

  fputs( "Enter employee name: ", stdout );
  if ( !fgets( name, nameSize, stdin ) )
  {
    fputs( "Error reading Emp Name\n", stderr );
    return false;
  }

  fputs( "Enter employee position: ", stdout );
  if ( !fgets( pos, posSize, stdin ) )
  {
    fputs( "Error reading Emp Position\n", stderr );
    return false;
  }
  return true;
}

createNode看起来就像

代码语言:javascript
复制
struct node *createNode( int id, const char *name, const char *pos )
{
  struct node *n = calloc( 1, sizeof *n );
  if ( n )
  {
    n->Name = calloc( strlen( name ) + 1, sizeof *n->Name );
    if ( !n->Name )
    {
      fputs( "Allocation failure on n->Name!\n", stderr );
      free( n );
      n = NULL;
    }
    else
      strcpy( n->Name, name );

    n->Pos = calloc( strlen( n->Pos ) + 1, sizeof *n->Pos );
    if ( !n->Pos )
    {
      fputs( "Allocation failure on n->Pos!\n", stderr );
      free( n->Name );
      free( n );
      n = NULL;
    }
    else
    {
      strcpy( n->Pos, pos );
    }
  }
  return n;
}

insertList看起来就像

代码语言:javascript
复制
void insertList( struct node **head, struct node *n )
{
  if ( !*head )
    *head = n;
  else
  {
    struct node *cur = *head;
    while ( cur->next != NULL )
      cur = cur->next;
    cur->next = n;
  }
}

这使您可以隔离地测试每一段代码,并使通过推理和修复代码变得更加容易。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74193067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档