Error al imprimir caracteres

Iniciado por JoseCheO, 3 Febrero 2014, 18:09 PM

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

JoseCheO

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

typedef struct nodo {
   char nombre[20];
   int cedula;
   float precio;
   struct nodo *siguiente;
} tipoNodo;
typedef tipoNodo *pNodo;
typedef tipoNodo *Lista;

Lista lista = NULL;

void InCompra ();
void Insertar(Lista *plista, char nom[20],int pci,float ppre);
int ListaVacia(Lista plista);
void BorrarLista(Lista *);
void MostrarLista(Lista plista);
void Borrar (Lista *plista, int bci);

void InBorrar(){
   
   int c=0;
   printf("Cedula de Comprador a Borra:          ");
   scanf("%d",&c);
   Borrar(&lista,c);
   printf("\n\nComprador Eliminado\n\n");
   
      
}
void mostrar_menu() {
   printf("\n\nMenu:\n=====\n\n");
   printf("1.- Agregar Compra\n");
   printf("2.- Borrar Compra\n");
   printf("3.- Mostrar Lista de Compras\n");
   printf("4.- Salir\n\n");
   printf("Escoge una opcion: ");
   printf("\n \n ");
}
void InCompra(){
   
   char n[20];
   int c;
   float pe;
   printf("\n \n");
   printf("Nueva Compra");
   printf("\n \n");
   printf("Nombre:    ");
   scanf("%20[^\n]",n);
   printf("Cedula:    ");
   scanf("%d",&c);
   printf("\n");
   printf("Precio de Compra:    ");
   scanf("%f",&pe);
   printf("\n");      
   printf("===========================================================");
   printf("\n \n");
   Insertar(&lista, n,c,pe);
   }



void Borrar(Lista *lista, int v) {
   pNodo anterior, nodo;
   
   nodo = *lista;
   anterior = NULL;
   while(nodo && nodo->cedula < v) {
      anterior = nodo;
      nodo = nodo->siguiente;
   }
   if(!nodo || nodo->cedula != v) return;
   else { /* Borrar el nodo */
      if(!anterior) /* Primer elemento */
         *lista = nodo->siguiente;
      else  /* un elemento cualquiera */
         anterior->siguiente = nodo->siguiente;
      free(nodo);
   }   
}

void Insertar(Lista *lista, char no[20],int ci, float pre) {
   pNodo nuevo, anterior;
   /* Crear un nodo nuevo */
   
   nuevo = (pNodo)malloc(sizeof(tipoNodo));
   nuevo->nombre[20] = no[20];
   nuevo->cedula = ci;
   nuevo->precio = pre;
   /* Si la lista está vacía */
   if(ListaVacia(*lista) || (*lista)->precio > pre) {
      /* Añadimos la lista a continuación del nuevo nodo */
      nuevo->siguiente = *lista;
      /* Ahora, el comienzo de nuestra lista es el nuevo nodo */
      *lista = nuevo;
   } else {
      /* Buscar el nodo de valor menor a v */
      anterior = *lista;
      /* Avanzamos hasta el último elemento o hasta que el siguiente tenga
      un valor mayor que v */
      while(anterior->siguiente && anterior->siguiente->precio <=pre)
         anterior = anterior->siguiente;
      /* Insertamos el nuevo nodo después del nodo anterior */
      nuevo->siguiente = anterior->siguiente;
      anterior->siguiente = nuevo;
   }
   
}

int ListaVacia(Lista lista) {
   return (lista == NULL);
}

void BorrarLista(Lista *lista) {
   pNodo nodo;
   while(*lista) {
      nodo = *lista;
      *lista = nodo->siguiente;
      free(nodo);
   }
}

void MostrarLista(Lista lista) {
   pNodo nodo = lista;
   if(ListaVacia(lista)) printf("Lista vacia\n");
   else {
      printf("\nListado General\n");
      while(nodo) {
         printf("-> Nombres: %s     -> Cedula: %d  Precio: %.2f -> \n",nodo->nombre,nodo->cedula,nodo->precio);
         nodo = nodo->siguiente;
      }
      printf("\n");
   }

}


   
int main() {
      
   char opcion;
   
   
   do {
      mostrar_menu();
      opcion = getch();
      switch ( opcion ) {
      case '1': InCompra();
         break;
      case '2':InBorrar();
         break;
      case '3':MostrarLista(lista);
         break;
      case '4': exit( 1 );
      default: printf( "Opcion no valida\n" );
         break;
      }
   } while (opcion!='4');

   return 0;
   
}


Al mostrar lista... me los nombres aparecen unas letras raras

Belial & Grimoire

trata cambiando el scanf de nombres, usa el string %s
.                                 

x64core

revisa el array nombre puede que el buffer no sea inicializado ya que es una cadena y podrias no copiar el caracter nulo para denotar
la cadena. inicializa el array usando memset

Yoel Alejandro

#3
Hola José, estuve probando el código y veo que agrega bien la cédula y el precio, pero no el nombre.

El error está en la asignación del campo nombre. Recuerda que para copiar una cadena en otra no se puede simplemente con el operador de asignación (=), sino que debes hacerlo con strcpy, o mejor aún, para prevenir desbordamiento, con strncpy.

La función

strncpy( char* dest, char *src, size_t n )

copia un máximo de n caracteres de la cadena origen a la cadena destino. y luego debes agregar manualmente el nulo de terminación. En el código de la función Insertar, la línea:


nuevo->nombre[20] = no[20];


debe reemplazarse por


strncpy( nuevo->nombre, no, 20);
(nuevo->nombre)[20] = '\0';


donde los paréntesis en (nuevo->nombre) son necesarios puesto que el operador "[]" tiene mayor precedencia que el de acceso de miembro "->". Con ésto ya tu programa debe quedar bien :)

===================
Por cierto, recomiendo poner un getchar() al final de Imprimir, de manera que la lista permanezca impresa en pantalla hasta que el usuario presione una tecla.
También recuerda que getch() no es una función estándar de C, sino que funciona principalmente en compiladores de C para Windows. Usa getchar().
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)