Print a queue item by removing each item from it

Asked

Viewed 251 times

0

I’m making a program that receives a string with words separated by comma that separates these words and lines them up (Until then I was able to do it quietly), then the program has to go removing and printing the items, but I can not develop the function desenfileira, I even tried to base myself on other book codes.

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

    struct fila {
        char nome [30];
        char dado;
        struct fila *proximoPtr;    
    };
    typedef struct fila Fila;
    typedef Fila *PtrFila;
    void imprimeFila (PtrFila atualPtr);
    int ehVazia(PtrFila headPtr );
    //void dequeue(PtrFila *headPtr, PtrFila *tailPtr );
    void enqueue(PtrFila *headPtr, PtrFila *tailPtr, char nome[30]);

    int main(){
            PtrFila headPtr = NULL;
            PtrFila tailPtr = NULL;
        for ( ; ; ){
            char linha[1024];
            puts("Escreva Nomes Separados por Virgula");
            fgets(linha, 1024 , stdin);
            char item;
            char* tok;
            char* tmp = strdup(linha);

            tok=strtok(tmp, ",");
            int cont=0;
            while (tok != NULL) {
                cont++;
                enqueue( &headPtr, &tailPtr, tok);

                tok = strtok (NULL, ",");
            }
            imprimeFila(headPtr);
            //dequeue (&headPtr, &tailPtr); A função que não está funcionando

        }
    }
    /*void dequeue(PtrFila *headPtr, PtrFila *tailPtr ) {
        char aux;
        PtrFila tempPtr;

        aux = ( *headPtr )->aux;
        tempPtr = *headPtr; 
        *headPtr = ( *headPtr )->proximoPtr; 

        if ( *headPtr == NULL ) {
            *tailPtr = NULL; 
        } 

        free( tempPtr );
        imprimeFila(headPtr);
    } */

    int ehVazia( PtrFila headPtr ){
        return headPtr == NULL;
    }

    void imprimeFila( PtrFila atualPtr ){
        PtrFila inicioPtr;
        inicioPtr=atualPtr;
        if ( atualPtr == NULL ) {
            puts( "Fila esta vazia.\n" );
        } 

            atualPtr=inicioPtr;
            while ( atualPtr != NULL ) {
                printf( "%s --> ", atualPtr->nome );
                atualPtr = atualPtr->proximoPtr;
            } 

            puts( "NULL\n" );

        } 

    void enqueue( PtrFila *headPtr, PtrFila *tailPtr, char nome[30]){

        char * novalinha = strchr(nome, '\n');
        if (novalinha)
            *novalinha = '\0';  

        PtrFila newPtr; 
        newPtr=malloc(sizeof(Fila));

        if ( newPtr != NULL ) { 
            newPtr->dado = nome;
            newPtr->proximoPtr = NULL;

            strcpy( newPtr->nome,nome);


            if ( ehVazia( *headPtr ) ) {
                *headPtr = newPtr;
            } 
            else {
                ( *tailPtr )->proximoPtr = newPtr;
            } 

            *tailPtr = newPtr;
        } 
        else {
            printf( "%c nao foi inserido. Memoria nao foi disponibilizada.\n");
        } 
    } 
  • You don’t have to write your title up. It looks like you’re yelling at everyone here!

  • Do the tour to learn more about the site.

1 answer

0


Normally, for a queue, I would recommend creating a struct containing the two hands inicioPtr and fimPtr not having to keep passing references to their local variables; in fact, the problems in the dequeue() all have to do with type errors between base types and their pointers. But let’s see:

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

First, you forgot to include the header <string.h> to use strdup() and strcpy(). This works because the functions do not use data types defined in the header, but it is a bad habit. You must have taken some warnings when compiling complaining about this: please try to read and analyze the compiler messages when you compile your program.

struct fila {
    char nome [30];
    char * dado;
    struct fila *proximoPtr;    
};
typedef struct fila Fila;
typedef Fila *PtrFila;

In your line, you have a member nome type char[30] and a member dado type char. Later, in the enqueue(), you will take the name passed as parameter and copy it to the vector nome and mark a reference to it in the field dado, that does not hold it because it is a char. So I changed it to char *, a pointer to char, although it is not clear why you want a reference if you have already copied the name.

void dequeue(PtrFila *headPtr, PtrFila *tailPtr ) {
    PtrFila tempPtr;

    if (*headPtr == NULL) return;
    tempPtr = *headPtr; 
    *headPtr = ( *headPtr )->proximoPtr; 

    if ( *headPtr == NULL ) {
        *tailPtr = NULL; 
    } 

    free( tempPtr );
    imprimeFila(*headPtr);
}

To dequeue() proper is simple. You create a variable aux type char and signals to her a non-existent member aux of the line, which almost certainly is the dado that you renamed and forgot to refactor. But also after it does nothing with this variable, then I removed it completely.

Besides, at the end, you were passing by headPtr, which is a ptrFila *, instead of *headPtr, which is a ptrFila depending on the function imprimeFila() asks. It is for this reason that I personally do not like to create synonyms of style ptrX for X*. But it’s not an iron rule; some people like it and don’t get tangled up in it.

Finally, in the enqueue() we have two problems:

void enqueue( PtrFila *headPtr, PtrFila *tailPtr, char nome[30]){

    char * novalinha = strchr(nome, '\n');
    if (novalinha)
        *novalinha = '\0';  

    PtrFila newPtr; 
    newPtr=malloc(sizeof(Fila));

    if ( newPtr != NULL ) { 
        newPtr->dado = nome;
        newPtr->proximoPtr = NULL;

        strncpy( newPtr->nome,nome,30);


        if ( ehVazia( *headPtr ) ) {
            *headPtr = newPtr;
        } 
        else {
            ( *tailPtr )->proximoPtr = newPtr;
        } 

        *tailPtr = newPtr;
    } 
    else {
        printf( "%c nao foi inserido. Memoria nao foi disponibilizada.\n");
    } 
} 

First of all, you write strcpy( newPtr->nome,nome);. But what happens if the user enters a name with more than twenty-nine characters? This is a class of bugs that has already caused much damage out there, the so-called buffer overflows. Always prefer to use functions such as strncpy(), who receive the size of buffer output as parameter. For any function you think of the standard library, there is a version with n in the name that receives an extra parameter with the maximum number of characters to read or write. stncpy(), strncmp(), snprintf(), so on and so forth.

Make it a habit to check the amount of characters you are writing, triply if what you’re writing comes from the user. Sooner or later, someone will write something they shouldn’t and your software blows up...

  • Thank you very much ! Perfect explanation. I only adjusted it later as I would like and it worked correctly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.