Thread: Help needed.

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    22
    Rep Power
    0

    Help needed.


    Hello everyone. I am experiencing an unusual error when I am trying to run my programm. Its purpose is to acquire from the user #-$-% symbols and display them in order (example ##$%%)
    Well it compiles but the problem is somewhere in the while loop. It displays the message in order to get another entry but it doesnt let me to insert the symbol. The programm should stop taking symbols from the user when he enters any other symbol.

    Edit: The problem is with the scan command inside the while loop I think. It ignores it completely and I dont know why :S.
    Here is the code.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    typedef struct PinakasA
    {
            int size;
            char *pinA;
    }PinakasA;
    typedef struct PinakasB
    {
            int size;
            char *pinB;
    }PinakasB;
    typedef struct PinakasC
    {
            int size;
            char *pinC;
    }PinakasC;
    void initALL(PinakasA *a,PinakasB *b,PinakasC *c)
    {
         a->size=1;
         a->pinA=(char*)malloc(a->size*sizeof(char));
         b->size=1;
         b->pinB=(char*)malloc(b->size*sizeof(char));
         c->size=1;
         c->pinC=(char*)malloc(c->size*sizeof(char));
    }
    void change(PinakasA *a,PinakasB *b,PinakasC *c,char a[],int size);
    int main()
    {
        int size=1;
        char *pinakas;
        PinakasA a;
        PinakasB b;
        PinakasC c;
        initALL(&a,&b,&c);
        pinakas=(char*)malloc(size*sizeof(char));
        printf("Enter # or $ or % \n");
        scanf("%c",&pinakas[size-1]);
        
       if(pinakas[size-1]!='#' && pinakas[size-1]!='$' && pinakas[size-1]!='%')
        {
                              printf("Wrong entry\n");
        } 
        while(pinakas[size-1]=='#' ||  pinakas[size-1]=='$' || pinakas[size-1]=='%')
        {
                   size=size+1;
                   realloc(pinakas,size);
                   printf("Enter # or $ or % \n");
                   scanf("%c",&pinakas[size-1]);  
                
        } 
        change(&a,&b,&c,pinakas,size);
        system("pause");
    } 
    
    void change(PinakasA *a,PinakasB *b,PinakasC *c,char d[],int size)
    {
         int i;
         
         for(i=0;i<size;i++)
         {
                            if(d[i]=='#')
                            {
                                         a->size++;
                                         realloc(a,size);
                                         a->pinA[size-1]='#';
                            }
                            else if(d[i]=='$')
                            {
                                 b->size++;
                                 realloc(b,size);
                                 b->pinB[size-1]='$';
                            }
                            else if(d[i]=='%')
                            {
                                 c->size++;
                                 realloc(c,size);
                                 c->pinC[size-1]='%';
                            }
         }
        for(i=0;i<a->size;i++)
        {
                              
                              printf("%c\n",a->pinA[i]);
        }
        for(i=0;i<b->size;i++)
        {
                              printf("%c\n",b->pinB[i]);
        }
        for(i=0;i<c->size;i++)
        {
                              printf("%c\n",c->pinC[i]);
        }
    }
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    All your realloc calls are broken.

    > realloc(pinakas,size);

    If the memory is moved, then you've no idea where the new memory is.

    The correct form is
    Code:
    void *temp = realloc(pinakas,size);
    if ( temp != NULL ) {
        // success
        pinakas = temp;
    } else {
        // do something with the old pinakas
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    40
    Rep Power
    19
    3 similar struct is too much.

    I may use only 1 struct for all.
    Code:
    typedef struct P
    {
            int size;
            char *pin;
    } Pinakas;
    variables will be declared in fuction main()

    Code:
    int main()
    {
        Pinakas a, b, c;
    
        ...
    
       return 0;
    }
    But that is your style.

    I had corrected your code and gave some comments you can learn how it works.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct P
    {
            int size;
            char *pin;
    } Pinakas;
    
    
    void initALL(Pinakas *a,Pinakas *b,Pinakas *c)
    {
       /* a->size=1;
         a->pinA=(char*)malloc(a->size*sizeof(char)); 
         b->size=1;
         b->pinB=(char*)malloc(b->size*sizeof(char));
         c->size=1;
         c->pinC=(char*)malloc(c->size*sizeof(char)); */
         
        /* At begin, there is nothing !!! */
        
        a->size = 0;
        a->pin = NULL;
        b->size = 0;
        b->pin = NULL;
        c->size = 0;
        c->pin = NULL;    
    }
    
    void change(Pinakas *a,Pinakas *b,Pinakas *c,char a[],int size);
    
    int main()
    {
        int size=1;
        char *pinakas;
        Pinakas a, b, c;
        
        initALL(&a,&b,&c);
        pinakas=(char*)malloc(size*sizeof(char));
        
        /* Logical errer. 
           If first entry got no '#' || '$' || '%', you can not entry the loop ! 
           Change while-loop to do-loop may be better. Make realloc only when condition met.
           Use difference condition to exit loop.  
           Just use sizeof() in realloc() function. 
        */
          
          
        /*
        printf("Enter # or $ or % \n");
        scanf("%c",&pinakas[size-1]);
        
        if(pinakas[size-1]!='#' && pinakas[size-1]!='$' && pinakas[size-1]!='%')
        {
                              printf("Wrong entry\n");
        } 
        while(pinakas[size-1]=='#' ||  pinakas[size-1]=='$' || pinakas[size-1]=='%')
        {
                   size=size+1;
                   realloc(pinakas,size);
                   printf("Enter # or $ or % \n");
                   scanf("%c",&pinakas[size-1]);  
                
        } 
        */
           
        do {
            printf("Enter # or $ or %c\n", 37);  /* 37 = ascii code for % */
            scanf("%c",&pinakas[size-1]);
            if (pinakas[size-1]=='#' ||  pinakas[size-1]=='$' || pinakas[size-1]=='%') {
                ++size;
                pinakas=(char*)realloc(pinakas, size*sizeof(char));
            }
            else if(pinakas[size-1] != '.')
                printf("Wrong entry '%c'\n",pinakas[size-1]);
            getchar();        /* clear stdin buffer */
        } while(pinakas[size-1] != '.');
        pinakas[size-1] = '\n'; /* End of string */
         
        change(&a,&b,&c,pinakas,size);
        printf ("\n");
        
        system("pause");
        
        return 0;   /* Don't forget to return an integer. */
    } 
    
    void change(Pinakas *a,Pinakas *b,Pinakas *c,char d[],int size)
    {
         int i;
         
         for(i=0;i<size;i++)
         {
                            if(d[i]=='#')
                            {
                                         a->size++;
                                         /* realloc(a,size); 
                                            a->pinA[size-1]='#';*/
                                         /* a don't need to resize, but *pin need. */
                                         a->pin = (char*)realloc(a->pin, a->size * sizeof(char));
                                         a->pin[a->size-1] = d[i]; 
                            }
                            else if(d[i]=='$')
                            {
                                 b->size++;
                                 /* realloc(b,size);
                                    b->pinB[size-1]='$'; */
                                 /* b don't need to resize, but *pin need. */
                                 b->pin = (char*)realloc(b->pin, b->size * sizeof(char));
                                 b->pin[b->size-1] = d[i]; 
                            }
                            else if(d[i]=='%')
                            {
                                 c->size++;
                                 /* realloc(c,size);
                                    c->pinC[size-1]='%'; */
                                 /* c don't need to resize, but *pin need. */
                                 c->pin = (char*)realloc(c->pin, c->size * sizeof(char));
                                 c->pin[c->size-1] = d[i]; 
                            }
         }
        for(i=0;i<a->size;i++)
        {
                              
                              printf("%c",a->pin[i]);
        }
        for(i=0;i<b->size;i++)
        {
                              printf("%c",b->pin[i]);
        }
        for(i=0;i<c->size;i++)
        {
                              printf("%c",c->pin[i]);
        }
    }
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    22
    Rep Power
    0
    Thanks for your replies. I tried changing the realloc to
    Code:
    pinakas=(char*)realloc(pinakas, size*sizeof(char));
    but it still doesnt let me read the second symbol when it enters the while loop and I have no idea why it is doing it.(I fixed the reallocs at the function too btw.)

    Edit: When I try to change my while loop to a do-while loop it works, but I cant understand why it doesnt work with a while loop :chomp:
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    40
    Rep Power
    19
    Originally Posted by Uniflame
    but it still doesnt let me read the second symbol when it enters the while loop
    scanf put a char in pinakas and push '\n' back to read buffer. pinakas got '\n' in second loop ( your second input got 3rd loop). I put a trick with getchar() at the end of loop to get '\n' from read buffer (clear read buffer). It's not safe, but enough for your code assuming user input a character and enter. If user input 2 or three more character, it won't work. Using fflush(stdin); before scanf might be better.

    while loop and do-while loop are the same, but do-while safe your work. You don't need to type printf and scanf twice.

IMN logo majestic logo threadwatch logo seochat tools logo