Solved

strin*g_qu*ue

Posted on 2008-10-03
16
324 Views
Last Modified: 2010-04-15
I have implement a queue (in c) which take int values.When i try to modify this queue to hold string data i had a lot of problem.My code (i have make commend the precedent code )


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

typedef struct {
      //int dataitem;
     char dataitem[100];
    struct listelement *link;
}               listelement;

//listelement * AddItem (listelement * listpointer, int data);
listelement * AddItem (listelement * listpointer, char data[100]);
listelement * RemoveItem (listelement * listpointer);
void PrintQueue (listelement * listpointer);
void ClearQueue (listelement * listpointer);


//listelement * AddItem (listelement * listpointer, int data) {
listelement * AddItem (listelement * listpointer, char data[100]) {
    listelement * lp = listpointer;
      if (listpointer != NULL) {
            while (listpointer -> link != NULL)
            listpointer = listpointer -> link;
            listpointer -> link = (struct listelement  *) malloc (sizeof (listelement));
            listpointer = listpointer -> link;
            listpointer -> link = NULL;
            listpointer -> dataitem = data;
      return lp;
    }
    else {      listpointer = (struct listelement  *) malloc (sizeof (listelement));
            listpointer -> link = NULL;
            listpointer -> dataitem = data;
      return listpointer;
    }
}

listelement * RemoveItem (listelement * listpointer) {
    listelement * tempp;
    //printf ("Element removed is %d\n", listpointer -> dataitem);
      printf ("Element removed is %s\n", listpointer -> dataitem);
    tempp = listpointer -> link;
    free (listpointer);
    return tempp;
       }

void PrintQueue (listelement * listpointer) {
     if (listpointer == NULL)
            printf ("queue is empty!\n");
            else
            while (listpointer != NULL) {
                  printf ("%d\t", listpointer -> dataitem);
                  listpointer = listpointer -> link;
            }
    printf ("\n");
      }

void ClearQueue (listelement * listpointer) {
       while (listpointer != NULL) {
            listpointer = RemoveItem (listpointer);
    }
}



int main () {
      listelement listmember, *listpointer;
      //int     data;
      char data[100];
      int i;
    listpointer = NULL;
   



      for (i=0;i<4;i++){
          printf ("Enter data item value to add");
            //scanf("%d", &data);
            gets(data);
            listpointer = AddItem (listpointer, data);
      }


////////////////////////////////////////////////////
//remove
/*      if (listpointer == NULL)
                printf ("Queue empty!\n");
            else
                listpointer = RemoveItem (listpointer);
                  
*/
////////////////////////////////////////////////////            
//print            
      
PrintQueue (listpointer);
            
////////////////////////////////////////////////////
          
            

/*            printf ("Invalid menu choice - try again\n");
            
      }
    }
    //ClearQueue (listpointer);
}*/                        /* main */


          
system("pause");      
      return 0;}
0
Comment
Question by:Tom211
16 Comments
 
LVL 9

Expert Comment

by:jhshukla
ID: 22638702
in AddItem change
listpointer -> dataitem = data; to
strncpy(listpointer->dataitem, data, 100);

I strongly recommend defining 100 as a macro (i.e. #define) or a const unsigned int and use that instead of literal 100.
#define DATA_SIZE 100
or
const int DATA_SIZE = 100;


The problem is that C does not allow array assignments like the way you used.
C++ style strings have overloaded assignment operator and you could use that to make your code look nicer. Google is your friend.
0
 
LVL 23

Expert Comment

by:Mysidia
ID: 22639635
This queue sample implementation is really familiar
Reminiscent of A.D. Marshall 1999
http://www.cs.cf.ac.uk/Dave/C/node11.html#SECTION001140000000000000000

In any event;  I suggest  allocating strings dynamically within the queue
and that you enqueue the pointer instead of 100 bytes of structure data.

Alternatively, use a dynamically-growable structure.
typedef struct {
      //int dataitem;
    struct listelement *link;
     char dataitem[0];
}               listelement;

and thus something sort of like...
 listpointer -> link = (struct listelement  *) malloc (sizeof (listelement) + strlen(data) + 1);
 memcpy(listpointer->dataitem, data, strlen(data)+1);

The growable string must be the final element in this case.

a more flexible form, and the "right way" to do this is  to have a pointer member.

typedef struct {
     char *dataitem;
      //int dataitem;
    struct listelement *link;
}               listelement;


and in the code, you allocate the pointer before copying the string,
and free the pointer when cleaning up the structure.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22640154
>>  i had a lot of problem

What kind of problems ? Can you elaborate a bit on them ? So we know what you're talking about :)
0
 

Author Comment

by:Tom211
ID: 22641350
Now i change the implementation.The new queue is better i think.But i steel have problem with the output.
The problem is in the function queue enqueue (i think).(when print the item of the queue).I do not not know what is going wrong.Can you help me to correct the problem?


Code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _node {
   char element[10];
   struct _node *next;
} node;

typedef struct {
   node *front;
   node *back;
} queue;

queue init ()
{
   queue Q;

   /* Create the dummy node */
   Q.front = (node *)malloc(sizeof(node));
   Q.front -> element[10] = ' ';
   Q.front -> next = NULL;
   Q.back = Q.front;
   return Q;
}

int isEmpty ( queue Q )
{
   return (Q.front == Q.back);
}

int isFull ( queue Q )
{
   return 0;
}

char front ( queue Q )
{
   if (isEmpty(Q)) {
      fprintf(stderr,"front: Queue is empty\n");
      return '\0';
   }
   return Q.front -> element[10];
}

//queue enqueue ( queue Q , char ch )
queue enqueue ( queue Q , char ch[10] )
{
      
   node *C;
   if (isFull(Q)) {
      fprintf(stderr,"enqueue: Queue is full\n");
      return Q;
   }

   /* Create new node */
   C = (node *)malloc(sizeof(node));
   C -> element[10] = ch;
   C -> next = NULL;

   /* Adjust the back of queue */
   Q.back -> next = C;
   Q.back = C;

   return Q;
}

queue dequeue ( queue Q )
{
   if (isEmpty(Q)) {
      fprintf(stderr,"dequeue: Queue is empty\n");
      return Q;
   }

   /* Make the front of the queue the new dummy node */
   Q.front = Q.front -> next;
   Q.front -> element[10] = '\0';

   return Q;
}

void print ( queue Q )
{
   node *G;

   G = Q.front -> next;
   while (G != NULL) {
      //printf("%c", G -> element);
      printf("%s\n", G -> element);
      G = G -> next;
   }
}

int main ()
{
   queue Q;
   int i;
   char item[10];

   Q = init();// printf("Current queue : "); print(Q); printf("\n");
   for(i=0;i<3;i++){
   printf("give item\n");
   
   gets(item);
   
   Q = enqueue(Q,item); printf("Current queue\n : "); print(Q); printf("\n");
   }
system("pause");
return 0;}

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22642799
>> But i steel have problem with the output.

And what is the problem you have with the output ? What output did you get, and what output did you expect ? The more information you give us, the better we'll be able to help you.
0
 

Author Comment

by:Tom211
ID: 22643969
Output's problem is:
program is asked to give  item  (as a string) and then print the items of the queue.The problem is that when the program print the output of the queue is not the items but something strangely  symbols.I am sure that the problem is in the function queue enqueue.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22644228
>>    Q.front -> element[10] = ' ';

That's incorrect. You're setting the 11-th element of an array that has only 10 elements. In other words, you're overwriting some other memory location.

Similarly elsewhere in the code.


>>    C -> element[10] = ch;

You can't assign a string like that. Use strcpy instead :

        http://www.cplusplus.com/reference/clibrary/cstring/strcpy.html


>> int isFull ( queue Q )
>> {
>>    return 0;
>> }

Interesting implementation for isFull ;)



Also : why do you have an extra item in the queue ?
0
 

Author Comment

by:Tom211
ID: 22644712
Ok i correct the queue.
Now how have you any idea how to modify the function  int isFull ( queue Q )
???

0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 53

Expert Comment

by:Infinity08
ID: 22644922
>> Ok i correct the queue.

So, it's working now ?


>> Now how have you any idea how to modify the function  int isFull ( queue Q )

You need to return a value that indicates whether the queue is full or not :) (1 if full, 0 if not full)
0
 

Author Comment

by:Tom211
ID: 22645011
So, it's working now ?

It work fine.It prints all the values right.
Thanks a lot.


For the function  int isFull ( queue Q )

>> int isFull ( queue Q )
>> {
>>    return 0;
>> }

I don't  know how to check if the queue is full or not.
 


 
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22645390
>> I don't  know how to check if the queue is full or not.

You define when it's full ... You've implemented it as a linked list, so you can ignore the size, but then why have an isFull method at all ?
0
 

Author Comment

by:Tom211
ID: 22648501
I finish with queue (with link list).Now i try to implement queue with array.
I try this code (and try again to convert it to have string variables).
I have problem in function  queue enqueue ( queue Q , char ch[10] )  ,with strcpy.

The code is:

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


#define MAXLEN 100

   typedef struct {
      char element[MAXLEN];
      int front;
      int back;
   } queue;

   queue init ()
   {  queue Q;
      Q.front = 0;
      Q.back = MAXLEN - 1;
      return Q;
   }

   int isEmpty ( queue Q )
   {
         return (Q.front == (Q.back + 1) % MAXLEN);
   }

   int isFull ( queue Q )
   {
      return (Q.front == (Q.back + 2) % MAXLEN);
   }

   char front ( queue Q )
   {
      if (isEmpty(Q)) {
         fprintf(stderr,"front: Queue is empty\n");
         return '\0';
      }
      return Q.element[Q.front];
   }

   queue enqueue ( queue Q , char ch[10] )
   {
      if (isFull(Q)) {
         fprintf(stderr,"enqueue: Queue is full\n");
         return Q;
      }
      ++Q.back;
      if (Q.back == MAXLEN) Q.back = 0;
      //Q.element[Q.back] = ch;
        strcpy(Q.element[Q.back],ch);
      return Q;
   }

   queue dequeue ( queue Q )
   {
      if (isEmpty(Q)) {
         fprintf(stderr,"dequeue: Queue is empty\n");
         return Q;
      }
      ++Q.front;
      if (Q.front == MAXLEN) Q.front = 0;
      return Q;
   }

   void print ( queue Q )
   {
      int i;

      if (isEmpty(Q)) return;
      i = Q.front;
      while (1) {
         printf("%s", Q.element[i]);
         if (i == Q.back) break;
         if (++i == MAXLEN) i = 0;
      }
   }

   int main ()
   {
      queue Q;
        int i;
        char item[10];

      Q = init();
      for (i=0;i<3;i++){
      printf("Give the item");
        //scanf("%c",&item);
        gets(item);
        Q = enqueue(Q,item); printf("Current queue : "); print(Q); printf("\n");
        }

     
        
        system("pause");
return 0;   }
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22648517
>> I have problem in function  queue enqueue ( queue Q , char ch[10] )  ,with strcpy.

Again : can you describe what that problem is ? We can't read minds ;)
0
 

Author Comment

by:Tom211
ID: 22648679
The problem is than can not compile this source.
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 50 total points
ID: 22648850
>>         strcpy(Q.element[Q.back],ch);

Q.element is a string (array of characters).
Q.element[Q.back] is a character (the character in the string that is at position Q.back).

strcpy copies a string into another, so the first parameter has to be a string.
0
 

Author Comment

by:Tom211
ID: 22691896
Ok. I understant what's going wrong

Thanks Infinity08.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now