Autor Tema: Problemas con una pila en C

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

13 Mayo, 2021, 03:43 pm
Leído 2585 veces

URama

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 86
  • País: ec
  • Karma: +0/-0
  • Sexo: Masculino
Hola! Quiero hacer un programa en C que al instertat datos tipo char se guarden diferenciandolos en si són números, letras....
Por ejemplo:
se inserta <<* -1 2.1 cos>> el programa tiene que ser capaz de guardara * en un sitio, los enteros en otro, los double en otro i el cos igual.

En primera instancia lo que he hecho es este código:
Código: [Seleccionar]
#include<stdio.h>
#include <stdlib.h>
#include<math.h>
#include<ctype.h>
int main () {

    char  cadena[20];
    printf ("Write line of characters:\n");

    while(scanf ("%c", &cadena ) != EOF)
    {
       if (isalpha(cadena)){
            pop (cadena);
       }
    }

    for (int i=0; i<5; i++){
        int data = pop();
        printf("%d\n",data);
    }
 return(0);
}

Para guardar los datos los pongo en una pila push and pop (), el problema esta en que me aparece que pop siempre está vacia y falla el primer if dentro del while. Tampoco no sé si el while está bien
definido. Alguien podria ayudarme??
Muchas gracias!

13 Mayo, 2021, 04:05 pm
Respuesta #1

Abdulai

  • Moderador Global
  • Mensajes: 3,044
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
Código: (c) [Seleccionar]
    while(scanf ("%c", &cadena ) != EOF)
    {
       if (isalpha(cadena)){
            pop (cadena);
       }
    }

Ahi debería ir un push

13 Mayo, 2021, 05:52 pm
Respuesta #2

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,797
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
La función scanf lee un caracter a la vez y lo guarda en la dirección de memoria del objeto cadena. Si eso funciona, es por casualidad, ya que &cadena es un puntero a array de char, y lo correcto sería poner ahí un puntero a char.

Luego la función isalpha necesita que se le pase como argumento un char (en realidad, un int, pero para el caso vale igual, por las conversiones), pero le has pasado cadena, que es un array de char, el cual decae allí a un puntero a char.

No sé cómo has definido push y pop, pero si los has definido para alojar punteros, en cada iteración se te sobreescribirán los valores.

En general, creo que tendrías que tomar una decisión de diseño, a ver si vas a trabajar con datos que son caracteres individuales, o cadenas de caracteres.

Lo que yo haría es leer una línea completa de texto con fgets(cadena,sizeof(cadena),stdin) (gets ha sido eliminada de C),
en la variable cadena,
para no estar leyendo permanentemente datos externos,
y luego trabajar en forma más segura con la cadena almacenada.

Además, al guardar los datos (con push, como indica Abdulai), no sé si estás almacenando algún indicador que informe de qué tipo de caracter se trata.

13 Mayo, 2021, 06:49 pm
Respuesta #3

URama

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 86
  • País: ec
  • Karma: +0/-0
  • Sexo: Masculino
La función scanf lee un caracter a la vez y lo guarda en la dirección de memoria del objeto cadena. Si eso funciona, es por casualidad, ya que &cadena es un puntero a array de char, y lo correcto sería poner ahí un puntero a char.

Luego la función isalpha necesita que se le pase como argumento un char (en realidad, un int, pero para el caso vale igual, por las conversiones), pero le has pasado cadena, que es un array de char, el cual decae allí a un puntero a char.

No sé cómo has definido push y pop, pero si los has definido para alojar punteros, en cada iteración se te sobreescribirán los valores.

En general, creo que tendrías que tomar una decisión de diseño, a ver si vas a trabajar con datos que son caracteres individuales, o cadenas de caracteres.

Lo que yo haría es leer una línea completa de texto con fgets(cadena,sizeof(cadena),stdin) (gets ha sido eliminada de C),
en la variable cadena,
para no estar leyendo permanentemente datos externos,
y luego trabajar en forma más segura con la cadena almacenada.

Además, al guardar los datos (con push, como indica Abdulai), no sé si estás almacenando algún indicador que informe de qué tipo de caracter se trata.

Hola! He estado intentado hacerlo con fgets pero me surge otra duda. Fgets guarda por ejemplo 2 3 1 *, pero como puedo recorrer toda la cadena pera diferenciar entre numeros, etc...

Luego, para guardar los datos en la pila voy ha utilitzar un vector que me va a diferenciar entre numeros, funciones, operaciones... No lo voy a guardar directamente!

Muchas gracias por la ayuda!

13 Mayo, 2021, 07:18 pm
Respuesta #4

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,797
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
La cadena se recorre con while leyendo un caracter a la vez hasta hallar el final de la cadena.
Se analiza cada caracter como lo venías haciendo con ctype.
Los espacios en blanco se descartan.
La distincion entre digito, operación, etc., es algo definido por el programador. Yo ni usaría ctype en realidad.
Igual no sé si entiendo tu pregunta.

18 Mayo, 2021, 03:48 pm
Respuesta #5

URama

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 86
  • País: ec
  • Karma: +0/-0
  • Sexo: Masculino
La cadena se recorre con while leyendo un caracter a la vez hasta hallar el final de la cadena.
Se analiza cada caracter como lo venías haciendo con ctype.
Los espacios en blanco se descartan.
La distincion entre digito, operación, etc., es algo definido por el programador. Yo ni usaría ctype en realidad.
Igual no sé si entiendo tu pregunta.
Hola! Muchas gracias! Si perdon la pregunta no esta muy bien formulada.

Ahora me surge otra duda, quiero hacer una pila LIFO de manera que guarde arrays de dos dimensiones. Es decir, que para codificar un numero, por ejemplo 2 será {0,2} entre dentro de pila, igualmente para una + seria {1,0} y - seria {1,1}... Entonces la pila deberia quedarse:
{1,1}
{1,0}
{0,2}. Pero no tengo ni idea de como se puede apilar vectores, alguna sugerencia? Sólo sé apilar números independients. Aquí mi código:
Código: [Seleccionar]
typedef struct Pila
{
    char *data;
    struct Pila *seguent;
}Element[2];

typedef struct PilaUbicacio
{
    Element *inici;
    int tamany;
} Pila;

void inicialitzacio (Pila *tas);

int apilar(Pila *tas, char *data);
int desapilar(Pila *tas);
void visualitzar(Pila *tas); //Mostra tota la pila;
/* FI PILA */

/* VECTORS PER APILAR */
void nombres(char p);
void operacions(char p);
/* FI VECTORS PER APILAR */

int main([
{
   double vector[2]={0,1};
   apilar(vector);
}
void inicialitzacio (Pila *tas)
{
    tas->inici=NULL;
    tas->tamany=0;
}

int apilar(Pila *tas, char *data)
{
    Element *nou_element;if((nou_element =(Element *) malloc (sizeof (char)))==NULL) return -1;
    strcpy (nou_element->data, data);
    nou_element->seguent=tas->inici;
    tas->inici=nou_element;
    tas->tamany++;
}

int desapilar(Pila *tas)
{
    Element *sup_element;
    if (tas->tamany==0) return -1;
    sup_element=tas->inici;
    tas->inici=tas->inici->seguent;
    free (sup_element->data);
    free (sup_element);
    tas->tamany--;
    return 0;
}

void visualitzar(Pila *tas)
{
    Element *actual;
    actual=tas->inici;

    for (int i=0; i<tas->tamany; i++){
        printf("\t\t%s\n", actual->data);
        actual=actual->seguent;
    }
}
Lo he intentado de mil maneras para guardar un array pero no me sale. Sé que no debe ser char el struct pero ya no entiendo nada. Muchas gracias si alguien pudiera ayudarme!