2010-08-12 6 views
1

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

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

#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; 
} 

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

Спасибо

ответ

2

Прежде всего, все ваши функции всегда возвращают 0 - даже для ошибки. Жизнь была бы намного проще, если бы вы передали ранг как 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);, если вы наберете больше, Tha 9 символов, вы вполне ввинчивается, как он будет перезаписывать стек программы.

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

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

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

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

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

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, вам в конечном итоге придется позвонить free.

+0

Нет, вы не хотите '\ n' в формате 'scanf()', это может привести к ожиданию * новой * новой строки. И никогда не используйте 'gets': используйте' fgets' или пишите свой собственный 'getline'. – schot

+0

Это не решает проблемы для меня .... На самом деле меня попросили дать выбор только один раз ... на первой итерации ... IT продолжает исполнять случай 1 для остальных. – Flash

0

Я смущен относительно использования переменной «rank». Main использует его как индекс для последнего узла в массиве, а узлы используют его как ранжирование. Добавление узлов увеличивает его, но удаление узлов не уменьшает его.

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

Лично я бы написал структуру, чтобы инкапсулировать массив своими собственными функциями отслеживания индексов и добавления/удаления. Таким образом, Main может свободно читать в пользовательских параметрах и манипулировать рангом новых узлов, не беспокоясь о деталях структуры данных.

+0

Фактически, ранг структуры - это позиция в массиве, где хранится указатель на структуру – Flash

+0

, когда вы удаляете узел, вы перемещаете все узлы после него на один блок ниже. Но вы не понижаете ранг узлов, которые вы смещаете (поэтому их ранг будет не синхронизирован), и вы не уменьшаете основную рангную переменную (так что последующие добавления будут прыгать на позицию). Кроме того, когда вы перемещаете оставшиеся элементы, вы не очищаете последний. Таким образом, у вас будет двойной номер в конце вашего массива. – Marc

+0

да ... я вроде пропустил кодировку, что – Flash

0
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 loop in delete.

Смежные вопросы