this is my sample code to create a student record using singly linked list queue. my problem is that I want to insert a student number in the struct but it doesn't repeat when I input the same student number.

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

struct node
{

    char No[12],Name[24],crsysr[10];
    float gwa;
    struct node *next;
}*front,*rear,*temp,*front1;


struct node *rear=NULL;
struct node *tail=NULL;





int frontelement();
void insert(char *data, char *name,char *yearsec,float gwa);
void del();
void empty();
void display();
void create();
void queuesize();
void removeduplicate();
int count = 0;

void main()
{
    struct node* rear;
    int  ch, pos,i,e;
    char no[12], name[24],crsyr[10];
    float gwa,tgwa;
    create();
    while (1)
    {
        system("cls");
            printf("\n 1 - Insert Student Record");
            printf("\n 2 - Delete Student Record");
            printf("\n 3 - Front element");
            printf("\n 4 - Empty");
            printf("\n 5 - Remove Duplicate");
            printf("\n 6 - Display Record Student");
            printf("\n 7 - Queue size");
            printf("\n 8 - Exit");
            printf("\n Enter choice : ");
            scanf("%d", &ch);


        switch (ch)
        {
        case 1:
            system("cls");
            printf ("how Many student do you want to enter?: ");
            int n;
            scanf("%d",&n);
            for(int i=0; i<n; ++i)
            {
            system("cls");
            printf("Student %d",count+1);
            fflush(stdin);
            printf("\n Enter Student number : ");
            gets(no);
            printf("\n Enter Student name : ");
            gets(name);
            printf("\n Enter Student Year and Sec : ");
            gets(crsyr);
            fflush(stdin);
            printf("\n Enter Student gwa : ");
            scanf("%f", &gwa);
            insert(no, name, crsyr, gwa);
            count++;
            }
            printf("Press any key to contiue...");
            getch();
            system("cls");
            break;
        case 2:
            system("cls");
            del();
            break;
        case 3:
            system("cls");
            e = frontelement();
            if (e != 0)
                printf("Front element : %d", e);
            else
                printf("\n No front element in Queue as queue is empty");
                system("cls");
            break;
        case 4:
            empty();
            break;
        case 5:
            system("cls");
            removeduplicate();
            display();
            printf("Press any key to contiue...");
            getch();
            break;
        case 6:
            system("cls");
            display();
            printf("Press any key to contiue...");
            getch();
            system("cls");
            break;
        case 7:
            queuesize();
            break;
        case 8:
             exit(0);
        default:
            printf("Wrong choice, Please enter correct choice  ");
            break;
        }
    }
}


void create()
{
    front = rear = NULL;
}
void queuesize()
{
    printf("\n Queue size : %d", count);
}


void insert(char *data, char *name,char *yearsec, float gwa)
{
    if (rear == NULL)
    {
        rear = (struct node *)malloc(1*sizeof(struct node));
        rear->next = NULL;
        strcpy(rear->No, data);
        strcpy(rear->Name, name);
        strcpy(rear->crsysr, yearsec);
        rear->gwa=gwa;
        front = rear;
    }
    else
    {
        temp=(struct node *)malloc(1*sizeof(struct node));
        rear->next = temp;
        strcpy(temp->No, data);
        strcpy(temp->Name, name);
        strcpy(temp->crsysr, yearsec);
        temp->gwa=gwa;
        temp->next = NULL;

        rear = temp;
    }
}


void display()
{
    front1 = front;
    int i;
    if ((front1 == NULL) && (rear == NULL))
    {
        printf("Queue is empty");
        return;
    }
        printf("Student Number\t\tName\t\tSection\t\tGwa\n\n");

    while (front1 != rear)
    {
        printf("%s \t",front1->No);
        printf("%s \t",front1->Name);
        printf("%s \t",front1->crsysr);
        printf("%.2f \t", front1->gwa);
        front1 = front1->next;
        printf("\n");


    }
    if (front1 == rear)
        printf("%s \t",front1->No);
        printf("%s \t",front1->Name);
        printf("%s \t",front1->crsysr);
        printf("%.2f\t", front1->gwa);
        printf("\n");
}

void del()
{
    front1 = front;

    if (front1 == NULL)
    {
        printf("\n Error: Trying to display elements from empty queue");
        return;
    }
    else
        if (front1->next != NULL)
        {
            front1 = front1->next;
            printf("\n Dequed Student num : " );
            puts(front->No);
            printf("\n Dequed Name : ");
            puts(front->Name);
            printf("\n Dequed Year and section : ");
            puts(front->crsysr);
            printf("\n Dequed GWA : %f", front->gwa);

            free(front);
            front = front1;
        }
        else
        {
            printf("\n Dequed Student Num : ", front->No);
            printf("\n Dequed Name : ", front->Name);
            printf("\n Dequed Year and section :", front->crsysr);
            printf("\n Dequed GWA : %f", front->gwa);
            free(front);
            front = NULL;
            rear = NULL;
        }
        count--;
}

int frontelement()
{
    if ((front != NULL) && (rear != NULL))
        return(front->No,front->Name,front->crsysr,front->gwa);
    else
        return 0;
}

void empty()
{
     if ((front == NULL) && (rear == NULL))
        printf("\n Queue empty");
    else
       printf("Queue not empty");
}


void removeduplicate() {
    // empty list
    if (rear == NULL) return;

    // element with one list .. nothing to remove
    if (rear == tail) return;

    struct node * previous = rear;
    struct node * current = rear->next;
    struct node * newcurrent = rear;
    struct node * temp;

    while (current != NULL) {

        newcurrent = rear;

        while (newcurrent != current) {
            if (strncmp(newcurrent->No == current->No)) {
                temp = current;
                previous->next = current->next;
                current = current->next;
                printf("Deleting %s \n", temp->No);
                free(temp);
                break;
            }

            newcurrent = newcurrent->next;
        }

        if (newcurrent == current) {
            previous = current;
            current = current->next;
        }
    }

    tail = previous;
}

Recommended Answers

All 2 Replies

The usual way to avoid duplicate entries is to search for a matching entry before inserting. It will be helpful to have a find_by_id(char *id) function that you can code and test separately before worrying about insertions. It should search the list for an entry with the given ID number and return a pointer to the first or only matching entry, or NULL if that ID wasn't found in the list. Once that's coded and tested, you can use it in your insert() function with something like:

    if (find_by_id(data) != NULL)
    {
        // report attempt to insert a duplicate ID
    }

You can reuse that function in any other code that might need to search for a student with a given ID number. I don't know what your application needs to do when an attempt to add a duplicate ID is detected. There's no return value from insert() that you can use to inform the caller that the duplicate entry couldn't be added.

By the way, it looks like you have missing {} braces in the last if statement in your display function. That's kind of an illustration that it's usually not worth trying to code a function before you're ready to write code to test it. By the time you finish testing the insert logic (needed to get data into the list), you may have forgotten some details of why you wrote the display() code the way you did.

By the way, using '\t' tab characters for output alignment is something to avoid in serious code. It's okay for quick-and-dirty programs, that only you will run, but unreliable for anything you will distribute to others. Different display devices or print formatters can have different ideas about where the tab stops are. The printf() function has nice features for controlling field sizes and you should learn to use them. For example, you could get that single-line display with one printf call:

        printf("%11s  %23s  %9s  %4.2f\n",
            front1->No,
            front1->Name, 
            front1->crsysr,
            front1->gwa);

As a side note: if you have any choice in the matter, never use void main() in C, or especially in C++. Always use int main(int argc, char argv[]), or at least int main().

The void main() form is a non-standard extension specific to some older, non-standard C compilers, most notably Turbo C++. No C or C++ compilers newer than 1992 will accept void main()) without at least a warning. Compiler extensions are an acceptable and often necessary thing, to be sure, but you need to be aware that this is what you are using.

I know that many professors - especially in India, Pakistan, and the Phillipines - still use Turbo C, and some will insist on you using void main(). In some cases, the compiler is mandated across the entire national university system, or at least it was in the past. Be aware that this is not going to be usable in most other contexts.

A similar note should be made regarding fflush(stdin), as the standard version of fflush() should not be applied to input buffers such as stdin - again, some older C compilers allow it, but it isn't standard, and trying to use it elsewhere will cause undefined behavior (compiler-specific results) or even an error message. There really isn't any standard way to flush stdin, though a sacrificial fgets() should at least drop any excess characters. Oh, and gets() is not exactly the safest function - you generally should replace it with fgets() to ensure that the buffer has a defined maximimum size.

On side note, which scanf() is a standard I/O function, it is generally agreed that the equivalent combination of fgets() and sscanf() instead, again to reduce the risk of buffer overruns. Similarly, in modern C, it is recommended that you use the newer standard function strncpy() rather than strcpy(), as that also delimits the size of the copied substring. This probably won't be available in an older C compiler, however.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.