Массив реализации указателей в C

Hii,

Я пытался записать программу... У нас есть структура, которая имеет поле разряда и поле имени. Указатель на эту структуру хранится в массиве фиксированного размера. Я реализовал его следующим образом, и у меня есть определенные проблемы... Код, который я написал:

 #include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct 
{
 int rank;
 char *name;
}node;

int insert(node **a , char name[] , int *rank)
 {
 if(*rank >= 5)
  {
   printf("\n Overflow ");
   return 0;
  } 
  (*rank)++;
  node *new = (node *)malloc(sizeof(node));
  new->name = name;
  new->rank = *rank;
  a[*rank] = new;

  return 0;
 } 

int delete(node **a , int *rank)
 {
  int i = *rank;
  if(*rank<0)
   {
    printf("\n No elements");
    return 0;
   }
   printf("\n Deleting %d , %s ",((a[*rank]))->rank,((a[*rank]))->name);
   printf("\n Reordering the elements ");
   while(i<5)
    {
     a[i] = a[i+1];
    }  
  return 0;
 }

 int display(node **a , int rank)
  {
   while(rank>0 && (a[rank])>0)
    {
     printf(" rank = %d    name = %s \n",((a[rank])->rank),((a[rank])->name));
     rank--;
    }            
    return 0;
  }

int main()
 {
  node *a[5] = {NULL};
  char ch = 'y';
  int choice,rank = -1;
  char name[10];
  while(ch!='n' || ch!= 'N')
   {
    printf("\n Enter 1 to insert , 2 to delete , 3 to display and 4 to exit \n");
    scanf("%d",&choice);
    switch(choice)
     {
      case 1:
        printf("\n Enter name to insert");
        gets(name);
        insert(a,name,&rank);
        break;
      case 2:
        printf("\n Enter rank to delete ");
        scanf("%d",&rank);
        delete(a,&rank);
        break;
      case 3:
        display(a,rank);
        break;
      case 4:
        exit(0);
      default:
        printf("\n Invalid choice...please enter again ");
        break;
     } 
    ch = getchar();
  }
 return 0;
 } 

Первой вещью является система, автоматически берет выбор за исключением первого раза... (я не мог найти отказ там...), и я немного смущен этим материалом указателя... Посмотрите если в порядке... Любые исправления приветствуются и дайте мне некоторое объяснение относительно того, почему неправильно и как мы shd делаем это...

Спасибо

1
задан James 12 August 2010 в 14:21
поделиться

3 ответа

Прежде всего, все ваши функции всегда возвращают 0 - даже в случае ошибки. Жизнь была бы намного проще, если бы вы передали rank как int и вернули бы его новое значение.

rank = insert(a, name, rank); 
/* : */
/* : */
int insert(node **a , char name[] , int rank)  
{  
 if(rank >= 5)  
 {  
   printf("\n Overflow ");  
   return 0;  
 }   
 rank++;  
 node *new = (node *)malloc(sizeof(node));  
 new->name = name;  
 new->rank = rank;  
 a[rank] = new;  
 return rank;  
}

Прошло много лет с тех пор, как я последний раз использовал scanf , но, насколько я помню, вы должны учитывать каждый символ в потоке, что означает «Не забывайте Enter».

scanf("%d\n",&choice);  

Также с gets (name); , если вы наберете более 9 символов, вы сильно запутаетесь, так как это перезапишет стек вашей программы.

ОБНОВЛЕНИЕ: Кроме того, у вас есть два способа выйти из этой программы, за исключением того, что один никогда не сработает. Вы можете выбрать опцию «4», которая вызовет exit (0) . Поочередно в конце каждой команды вы ждете появления персонажа, прежде чем переступить через него. Похоже, вы хотите иметь возможность ввести «N» и выйти, за исключением того, что это не сработает:

while(ch!='n' || ch!= 'N') 

для этого, чтобы получить ложное значение, ch должно быть одновременно «n» и «N». Вы действительно хотите

while(ch!='n' && ch!= 'N') 

UPDATE2: Я только что заметил самую большую проблему в вашем коде. name везде в вашем коде указывает только на единственный массив, определенный в main (). Каждый раз, когда вы вводите новое имя, он перезаписывает этот массив, и поскольку каждый узел указывает на этот единственный массив, имя меняется везде. Вам нужно сделать копию. in insert ():

node *new = (node *)malloc(sizeof(node));     
new->name = strdup(name);    // use malloc internally.

Затем в delete () вам нужно будет освободить эту память (кстати говоря, вам нужно освободить и там узел ...)

printf("\n Deleting %d , %s ",((a[*rank]))->rank,((a[*rank]))->name);       
free(a[*rank]->name);
free(a[*rank]);
printf("\n Reordering the elements ");

Помните: всякий раз, когда вы вызываете malloc , вам в конечном итоге придется позвонить бесплатно .

2
ответ дан 2 September 2019 в 22:13
поделиться
 while(ch!='n' || ch!= 'N')
   {
    printf("\n Enter 1 to insert , 2 to delete , 3 to display and 4 to exit \n");
    scanf("%d",&choice); getchar();
    .
    .
    .
    //ch = getchar();
  }

Использование getchar() вместе со scanf() вызывает эту проблему. Так как '\n' после чтения символа в 'ch' идет как вход в scanf. Один из способов решения проблемы - прочитать '\n' с помощью дополнительной getchar() до того, как он будет прочитан gets(). Также вам следует изменить цикл while в delete.

0
ответ дан 2 September 2019 в 22:13
поделиться

I'm confused as to the use of the "rank" variable. Main uses it as an index to the last node in the array, and the nodes use it as a ranking. Adding nodes increases it, but deleting nodes doesn't decrease it.

In the very least, I'd suggest separate the index variable from the ranking variable to make the logic easier to follow.

Personally, I'd write a structure to encapsulate the array with its own index tracking and add/delete functions. That way Main is free to read in user options and manipulate rank of new nodes without worrying about data structure details.

0
ответ дан 2 September 2019 в 22:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: