[AYUDA] Con lista en C

Iniciado por agrey, 12 Diciembre 2012, 02:06 AM

0 Miembros y 1 Visitante están viendo este tema.

agrey

/*

El problema es que al ejecutar el comando splano ps deberia de insertar en la lista la informacion del proceso ps, pero al ejecutar el comando imprimir la lista esta vacia. Un saludo GRACIAS

*/


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <sys/resource.h>
#include <sys/wait.h>

struct proceso
{
   int pid;
   int prioridad;
   char *comando;
   char *fecha;
   char *status;
   
   struct proceso *sig;//apuntador a la siguiente estructura
};

typedef struct proceso _nodo;

_nodo *crearLista(_nodo *apuntador)
{
   apuntador = NULL;
   return apuntador;
}

_nodo *insertarEnLista(int pid,int prioridad,char *comando,char *fecha,char *status,_nodo *apuntador)
{
   _nodo *registroNuevo, *apuntadorAuxiliar;

   registroNuevo = (_nodo*) malloc(sizeof(_nodo));

   if(registroNuevo != NULL)
   {
      registroNuevo->pid = pid;
      registroNuevo->prioridad = prioridad;
      registroNuevo->comando = comando;
      registroNuevo->fecha = fecha;
      registroNuevo->status = status;

      if(apuntador == NULL)
         apuntador = registroNuevo;
      else
      {
         apuntadorAuxiliar = apuntador;

         while(apuntadorAuxiliar->sig != NULL)
            apuntadorAuxiliar = apuntadorAuxiliar->sig;
            
         apuntadorAuxiliar->sig = registroNuevo;
      }
   }
   
   return apuntador;

}

void imprimirLista(_nodo *apuntador)
{
   _nodo *apuntadorAuxiliar;

   apuntadorAuxiliar = apuntador;
   
   while(apuntadorAuxiliar != NULL)
   {
      printf("%d -> ",apuntadorAuxiliar->pid);
      printf("%d -> ",apuntadorAuxiliar->prioridad);
      printf("%s -> ",apuntadorAuxiliar->comando);
      printf("%s -> ",apuntadorAuxiliar->fecha);
      printf("%s -> ",apuntadorAuxiliar->status);
      apuntadorAuxiliar = apuntadorAuxiliar->sig;
   }
   
   printf("NULL \n");
   
   return;
}

int main()
{
   _nodo *inicioLista;
   
    inicioLista= crearLista(inicioLista);
   
    //inicioLista = insertarEnLista(5,12,"pwd","19/05","ACT",inicioLista);

   
int stop=1,n;

char *comando[1000],*p;
char *cadena = (char *)malloc(sizeof(char)*1000);


   while(1){
      printf("Introduzca el comando: ");
      p = fgets(cadena, 1000, stdin);
         if (strcmp(p,"\n")==0) {//si p nulo, salta error y sale del programa
         continue;
         
      }
       n = TrocearCadena(p,comando);
      
      if (0!=ProcesarComando(comando,&n, inicioLista)) break;
   
   }

   free(inicioLista);
   free(cadena);
   
   return EXIT_SUCCESS;
}

int TrocearCadena(char *p, char *trozos[1000]){
   int i=1;
   if ((trozos[0]=strtok(p," \n\t"))==NULL)
   return 0;
   while ((trozos=strtok(NULL," \n\t"))!=NULL)//busca los delimitadores y
   i++;
   return i;
}

int ProcesarComando(char *coman[],int *n,_nodo *listaProcesos){
   
   if(strcmp(coman[0],"splano")==0){splano(coman,listaProcesos,n);}
   else if(strcmp(coman[0],"imprimir")==0){imprimirLista(listaProcesos);}
         
   return 0;
   
}

int splano(char *cadena[],_nodo *listaProcesos,int *n){
   _nodo *iniciolista;
   long tiempo= time(NULL);
   char * fecha = ctime(&tiempo);
   int which = PRIO_PROCESS;
   char *aux;
   int pid_hijo;
   int *espera = NULL;
   int i=0;
   int err=0;
   pid_hijo = fork();
      if(pid_hijo ==0){
              if(cadena[*n-1][0]=='@'){
         aux = cadena[*n-1];
         aux[0]=' ';
         if(setpriority(which,execvp(cadena[1],&cadena[1]),atoi(aux))<0){
               perror ("setprio");
               }
         }else{
         
         if(execvp(cadena[1],&cadena[1])==-1){perror("splano-EXEC");}
         

         }

      }else if(pid_hijo ==-1)perror("splano-fork");
         
               
         

   iniciolista = insertarEnLista(pid_hijo,getpriority(which,0),cadena[1],"act",fecha,listaProcesos);
   
   
}

twins

Cual es el proposito del programa, es decir que entrega como resultado despues de ejecutarlo?

agrey

#2
Es un trozo de codigo de un shell, una vez compilas y ejecutas dentro del programa introduces:
>>splano ls (ls o cualquier otro comando como ps)
(aqui sale el listado de tu directorio despues de hacer el ls)
(intro)
>>imprimir
(Aqui tendria que devolver la informacion recogida en la funcion splano del comando ls que es su Pid , Prioridad,fecha,el comando que se ejecuto(ls) y su estado)

twins

si es una lista enlazada el puntero que apunta al siguiente nodo debe de ser del mismo tipo de dato, ose en este caso struct proceso *sig;
struct proceso
{
   int pid;
   int prioridad;
   char *comando;
   char *fecha;
   char *status;

       //ojo con esta parte
   struct registro *sig;//apuntador a la siguiente estructura

};

agrey

#4
Si tienes razon de ese fallo no me di cuenta, pero creo que el error es de como le paso los punteros por eso nunca me llega a guardar en la lista. Si tu haces un imprimir lista dentro de la funcion splano si que imprime los datos pero si los quieres volver a listar desaparecen.

twins

Por mas que trato no he podido comprender el codigo ajajaja, ademas yo uso un metodo diferente para crear las funciones solo logre ingresar los datos a la lista he imprimirlos por que lo demas no comprendo cual es su objetivo.
Dime una cosa esta es una especie de tarea? porque si es asi debe tener el enunciado talvez con eso logre entender que es lo que piden.  ;D

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct proceso{
   int pid;
   int prioridad;
   char *comando;
   char *fecha;
   char *estado;
   struct proceso *sig;
}nodo;
void insertarEnLista(int pid,int prioridad,char comando[],char fecha[],char estado[],nodo **lista);
void imprimirLista(nodo **lista);
int main(void){
    nodo *lista=NULL;
    insertarEnLista(5,12,"pwd","19/05","ACT",&lista);
insertarEnLista(5,12,"pwd","19/05","ACT",&lista);
insertarEnLista(5,12,"pwd","19/05","ACT",&lista);
insertarEnLista(5,12,"pwd","19/05","ACT",&lista);
imprimirLista(&lista);
return(0);
}
void insertarEnLista(int pid,int prioridad,char comando[],char fecha[],char estado[],nodo **lista){
    nodo *nuevo,*aux=*lista;
nuevo=(nodo*)malloc(sizeof(nodo));
    if(nuevo!=NULL){
nuevo->pid=pid;
        nuevo->prioridad=prioridad;
        nuevo->comando=comando;
        nuevo->fecha=fecha;
        nuevo->estado=estado;
        if(*lista==NULL)
*lista=nuevo;
        else{
    while(aux->sig!=NULL)
aux=aux->sig;
            aux->sig=nuevo;
        }
    }
else
printf("no se dispone de memoria suficiente\n");
}
void imprimirLista(nodo **lista){
    nodo *aux=*lista;
while(aux!=NULL){
printf("[%d]->",aux->pid);
        printf("[%d]->",aux->prioridad);
        printf("[%s]->",aux->comando);
        printf("[%s]->",aux->fecha);
        printf("[%s]->",aux->estado);
        aux=aux->sig;
puts("\n");
    }
}

BlackZeroX

#6
Te dejo una pequeña libreria que hace ya unos meses atras me cree para tratar listas de manera mas generica en C.

list.h


#ifndef CSLIST_H_INCLUDED
#define CSLIST_H_INCLUDED

#include <stdbool.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>

typedef
enum {
    LIST_CMP_EQUAL          = 0x0,
    LIST_CMP_LESS_THAT      = 1,
    LIST_CMP_GREATER_THAT   = -1
} list_cmp_t;

typedef enum {
    LIST_SORT_ASC,      /* Indica que se copiaran los elemento antes del elemento indicado. No usar en conjunto de LIST_COPY_RIGHT. */
    LIST_SORT_DESC      /* Indica que se copiaran los elementos despues del elementos indicado. No usar en conjunto de LIST_COPY_LEFT. */
} list_sort_t;

typedef void*               list_t;
typedef list_t*             list_ptr_t;
#define LIST_NULL           NULL

typedef intptr_t            list_value_t;
typedef list_value_t*       list_value_ptr_t;
#define LIST_VALUE_NULL     NULL

typedef list_value_ptr_t    list_item_t;
typedef list_item_t*        list_item_ptr_t;
#define LIST_ITEM_NULL      NULL

typedef size_t              list_size_t;
typedef list_size_t*        list_size_ptr_t;

/** Definición de callback que se encarga de crear un duplicado del list_value_t indicado en el parámetro value.
* @param value: list_value_t que se duplicara.
* @return Retorna el elemento list_value_t duplicado del parámetro value.
*/
typedef
list_value_t(*list_callback_clone_item)
(const list_value_t value);

/** Definición de callback que se encarga de destruir la memoria asignada al list_value_t.
* @param value: list_value_t que se liberara.
*/
typedef
void(*list_callback_release_item)
(const list_value_t value);

/** Definición de callback que se encarga comparar dos list_value_t.
* @param value1: list_value_t que se comparara con value2.
* @param value2: list_value_t que se comparara con value1.
* @return Retorna el resultado de la comparación.
*    LIST_CMP_LESS_THAT: Si value1 < value2.
*    LIST_CMP_EQUAL: Si value1 == value2.
*    LIST_CMP_GREATER_THAT: Si value1 > value2.
*/
typedef
list_cmp_t(*list_callback_compare_item)
(const list_value_t value1,
const list_value_t value2);

/** Crea una nueva lista de elementos list_value_t.
* @param clone_item: Apuntador a la función callback que retornara la copia del valor a asignar.
* @param release_item: Apuntador a la función callback que liberara la copia del valor duplicado en el list_callback_clone_item.
* @param clone_item: Apuntador a un proceso callback que se encarga de comparar los list_item_t.
* @return Retorna la nueva cola de datos queue_t que debera ser destruida con list_release().
*/
list_t
list_allocator(list_callback_clone_item clone_item,
               list_callback_release_item release_item,
               list_callback_compare_item compare_item);

/** Función que destruye una lista.
*/
void
list_release(list_t list);

/** Función que remueve TODOS los elementos de la lista.
* @return Retorna la cantidad de elementos removidos de la lista.
*/
list_size_t
list_clear(list_t list);

/** Función que agrega n cantidad de elementos repetidos (value) a la lista, reemplazando los existentes.
* @param list: Lista en la que se agregara value n veces.
* @param n: Cantidad de valores a agregar a la lista.
* @param value: Valor a agregar n veces a la lista.
* @return Retorna el primer elemento agregado; NULL si no se a agregado ningun elemento.
*/
list_item_t
list_assign(list_t list,
            list_size_t n,
            list_value_t value);

/** Función que agrega un elemento al final de la lista.
* @param list: lista a la cual se le agregara un elemento nuevo.
* @param value: Valor a agregar a la lista.
* @return Retorna el item en la lista.
*/
list_item_t
list_pushback(list_t list,
              list_value_t value);

/** Función que agrega un elemento al inicio de la lista.
* @param list: Lista a la cual se le agregara un elemento nuevo.
* @param value: Valor a agregar a la lista.
* @return Retorna el item en la lista.
*/
list_item_t
list_pushfront(list_t list,
               list_value_t value);

/** Función que agrega un elemento en la lista antes de un elemento indicado.
* @param item: Elemento pivote que esta dentro de una lista.
* @param value: Valor a agregar a la lista antes del pivote.
* @return Retorna el item en la lista.
*/
list_item_t
list_pushprev(list_item_t item,
              list_value_t value);

/** Función que agrega un elemento aen la lista despues de un elemento indicado como pivote.
* @param item: Elemento pivote que esta dentro de una lista.
* @param value: Valor a agregar a la lista despues del pivote.
* @return Retorna el item en la lista.
*/
list_item_t
list_pushnext(list_item_t item,
              list_value_t value);


/** Función que obtiene la lista a la cual pertenece un item.
* @param list: Lista de la cual se obtendra su primer elemento list_item_t.
* @return Devuelve la lista list_t a la cual pertenece dicho item; NULL si no pertenece a ninguna lista.
*/
list_t
list_getlist(list_item_t item);

/** Función que obtiene el primer elemento de una lista.
* @param list: Lista de la cual se obtendra su primer elemento list_item_t.
* @return Devuelve el primer list_item_t de la lista.
*/
list_item_t
list_begin(list_t list);

/** Función que obtiene el ultimo elemento de una lista.
* @param list: Lista de la cual se obtendra el ultimo elemento list_item_t.
* @return Devuelve el ultimo list_item_t de la lista.
*/
list_item_t
list_back(list_t list);

/** Función que verifica si una lista esta vacia.
* @param list: Lista que se verificara.
* @return Retorna:
*  True: si la lista esta vacia.
*  False: Si contiene por lo menos un elemento.
*/
bool
list_empty(list_t list);

/** Función que retorna el item anterior al inicado.
* @param item: Item pivote en la lista.
* @return Retorna el list_item_t anterior al indicado; NULL si no hay ningun item.
*/
list_item_t
list_before(list_item_t item);

/** Función que retorna el item siguiente al inicado.
* @param item: Item pivote en la lista.
* @return Retorna el list_item_t siguiente al indicado; NULL si no hay ningun item.
*/
list_item_t
list_after(list_item_t item);

/** Función que busca un valor a partir de un pivote indicado dentro de una lista.
* @param item: Elemento pivote desde el cual se empresara a buscar el valor indicado en value.
* @param value: Valor a buscar en la lista apartir de el pivote indicado.
* @return Retorna NULL si no se a encontrado dentro de la lista en caso
* contrario retorna el elemento .
*/
list_item_t
list_findnext(list_item_t item,
              list_value_t value);

/** Función que busca un valor a partir de un pivote indicado dentro de una lista.
* @param item: Elemento pivote desde el cual se empresara a buscar el valor indicado en value.
* @param value: Valor a buscar en la lista antes de el pivote indicado.
* @return Retorna NULL si no se a encontrado dentro de la lista en caso
* contrario retorna el elemento .
*/
list_item_t
list_findprev(list_item_t item,
              list_value_t value);

/** Función que intercambia los valores entre dos elementos cuales quiera, inclusive entre listas.
* @param item1: Elemento involucrado en el intercambio.
* @param item2: Elemento involucrado en el intercambio.
* @return Retorna TRUE si no hubo errores y FALSE si no se puedo intercambiar los dos elementos.
*/
bool
list_swap(list_item_t item1,
          list_item_t item2);

/** Función que elimina un list_item_t de su lista.
* @param item: Elemento que se extraera de su lista.
*/
void
list_erase(list_item_t item);

/** Función que mezcla dos listas generando una nueva lista que debera ser liberada con list_release().
* @param list1: Los elementos de esta lista se agregaran al inicio.
* @param list2: Los elementos de esta lista se agregaran al seguidos de los de list1.
* @return Retorna una nueva lista que contendran las copias de las dos listas espesificadas.
*/
list_t
list_join(list_t list1,
          list_t list2);

/** Función que retorna la cantidad de elementos en la lista.
* @param list: Lista de la cual se retornaran la cantidad de elementos almacenados en ella.
*
* @return Retorna la cantidad de elementos en la lista.
*/
list_size_t
list_size(list_t list);

/** Función que copia los elementos de una lista a otra.
* @param dst: Elemento pivote en donde se se hubicaran los elementos a copiar desde src.
* @param src: Elemento pivote de una lista que se le clonaran sus elementos para agregarlos en la lista destino dst.
* @param n: Cantidad máxima de elementos que copiaran.
*
* @return Retorna la cantidad de elementos agregados en la listda dst.
*/
list_size_t
list_copy(list_item_t dst,
          list_item_t src,
          list_size_t n);

/** Función que clona por completo una lista.
* @param list: Lista que será clonada.
*
* @return Retorna una nueva lista que debera ser liberada con list_release().
*/
list_t
list_clone(list_t list);

/** Función que ordena los elementos de una lista.
* @param list: lista que se ordenara.
* @param sort: Indica el modo en el que serán ordenados los elementos
* LIST_SORT_ASC/LIST_SORT_DESC:
*/
void
list_sort(list_t list,
          list_sort_t sort);

#endif // CSLIST_H_INCLUDED



Descargar


#define LOOP 1
...

uint32_t min(uint32_t a, uint32_t b) {
    return (a<b) ? a:b;
}

void swap(int32_t *a, int32_t *b) {
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}

int randomnumber(int32_t lower, int32_t upper) {
    if (min(lower, upper) != lower) {
        swap(&lower, &upper);
    }
    return lower + rand() % ((upper + 1) - lower);
}

...

    list_t      list = list_allocator(NULL, NULL, NULL);
    list_item_t item = LIST_ITEM_NULL;

    for (int k = 0; k <= LOOP; ++k) {

        puts("Eliminando datos.");
        list_clear(list);
        puts("Lista limpia.\n");
        puts("Ingresando datos.");
        for (uint_fast32_t i = 0; i <= 10000000; ++i) {
            list_pushback(list, randomnumber(i, i));
        }
        puts("fin de insercion de los datos.\n");
    /*
        for (item = list_begin(list); item != NULL; item = list_after(item))
            printf("%7.0d\t", (int)*item);
        printf("\n");
    */
        puts("Ordenando datos.");
        list_sort(list, LIST_SORT_ASC);
        puts("Fin de ordenacion de los datos.\n");
    /*
        for (item = list_begin(list); item != NULL; item = list_after(item))
            printf("%7.0d\t", (int)*item);
        printf("\n");
    */
    }
    list_release(list);



Dulces Lunas!¡.
The Dark Shadow is my passion.

agrey

la funcion splano hace lo siguiente:
El shell crea un proceso que ejecuta en segundo plano  el programa con sus argumentos, el programa es un ejecutable externo y puede llevar argumentos, si el ultimo argumento empieza con el caracter '@' se entiende de que el shell ejecutar el programa con la prioridad cambiada a otra prioridad.
la funcion splano del codigo funciona bien lo que no funciona es la parte insertarenlista dentro de la funcion splano, porque la inserccion en la lista se tiene que hacer desde splano no desde el main.
un saludo¡

rir3760

Cita de: agrey en 13 Diciembre 2012, 14:48 PM
la funcion splano hace lo siguiente:la funcion splano del codigo funciona bien lo que no funciona es la parte insertarenlista dentro de la funcion splano, porque la inserccion en la lista se tiene que hacer desde splano no desde el main.
Eso se debe a que, al llamar a la función "ProcesarComando", la variable "inicioLista" se pasa por valor:
int main()
{
   _nodo *inicioLista;
   
   /* ... */
   
   while(1){
      /* ... */
     
      if (0!=ProcesarComando(comando,&n, inicioLista)) /* <== */
         break;
   
   }

Por ello no importa lo que hagas con esta los cambios no se verán reflejados en la función principal (me refiero a main).

Para solucionarlo solo tienes que revisar con cuidado el ejemplo publicado por twins, en el se emula el paso por referencia y los cambios a tu programa son similares.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language