getline() !!!

Iniciado por chicainge, 13 Septiembre 2014, 16:40 PM

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

chicainge

HOLA, miren tengo un problema con esta programa en el getline() este al introducirle mas de un caracter me mete en un bucle he probado a introducirle un cin.ignore o un cin.get() pero nada sigue teniendo problemas el getline(), alguien que sepa su funcionamiento y me explique que le pasa, Gracias:) :-\ :-\


/*Se necesita un programa para gestión de una agencia matrimonial. Por cada cliente se
almacenarán los siguientes datos: nombre, edad, sexo (M,F), aficiones (Lectura,
Viajes, Deportes, Cine, Gastronomía, Ordenadores,
JuegosDeRol, Modelismo,Perros). Una persona puede tener ninguna, uno o
más aficiones. Implementar los subalgoritmos que permitan (definir previamente el tipo
de datos adecuado para almacenar esta información):
a) Introducir en la estructura los datos de una persona
b) Buscar una persona (por el nombre)
c) Dar de baja una persona (eliminar sus datos, se localiza por el nombre)
d) Casar. Dado el nombre de una persona, se busca una afín a ella, se presentan
por pantalla sus datos y se eliminan los dos de la base de datos. Una persona
será afín a otra (a efectos de Casar) si coinciden todas sus aficiones.*/

#include<iostream>
#include<string>

using namespace std;

typedef int listaficiones[3];

typedef struct{
 string nombre;
 unsigned edad;
 char sexo;
 listaficiones aficiones;
}cliente;

typedef cliente NClientes[100];

typedef struct {
   unsigned numero_de_clientes;
   NClientes NC;
}TListaClientes;

void inicializar_registro(TListaClientes &);
void menu();
void registrar(TListaClientes &);
bool buscar(string , int&,TListaClientes);
void mostrar(int , TListaClientes);
bool casar(string , TListaClientes &);
bool borrar(string, TListaClientes &);
bool afic_iguales(int, int&, TListaClientes);
void mosafi(int ,int,TListaClientes );

int main(){
   TListaClientes lista;
   string n;
   char c='\n';
   int nr;
   inicializar_registro(lista);
   menu();
   while(c!='E'){
   cin>>c;
   //toupper(c);
   switch(toupper(c)){
     case 'A' :
         registrar(lista);
         cout<<"Persona registrada."<<endl;
         break;
     case 'B' :
         cout<<"Nombre buscado: ";
         getline(cin, n);
         buscar(n,nr,lista);
         mostrar(nr,lista);
         break;
     case 'C' :
       cout<<"Nombre del cliente que desea borrar: ";
       getline(cin, n);
       if (borrar(n,lista)){
           cout<<endl<< "cliente borrardo."<<endl;
       }
       else cout<<"cliente no existe!!"<<endl;
     break;
     case 'D' : cout<<"Nombre del cliente que desea casar: ";
     getline(cin, n);
     if(casar(n,lista)) cout<<"operacion realizada"<<endl;
     else cout<<"afin no encontrado.";
    }
   }
}

void inicializar_registro(TListaClientes &lis){
 lis.numero_de_clientes=0;
}

void menu(){
 cout<<"A.Registrar persona."
 <<endl<<"B.Buscar persona por nombre."
 <<endl<<"C.Eliminar una persona."
 <<endl<<"D.Casar. Hay que dar un nombre."
 <<endl<<"E.Salir."<<endl;

}
void registrar(TListaClientes &l){
       int sexo;
       cout<<"Este es el registro numero"<<l.numero_de_clientes+1<<endl;
       cout<<"NOMBRE: ";
       getline(cin,l.NC[l.numero_de_clientes].nombre);
       //cin.ignore();
       //cin.get();
       cout<<"Sexo, 1.(masculino) 2.(femenino): ";
       cin>>sexo;
       if(sexo==1){
       l.NC[l.numero_de_clientes].sexo='M';
       }
       else l.NC[l.numero_de_clientes].sexo='F';
       cout<<"Edad: ";
       cin>>l.NC[l.numero_de_clientes].edad;
       cout<<"Elige 3 aficiones: "<<endl<<" 1.Lectura "<<endl<<" 2.Viajes "<<endl<<" 3.Deportes "<<endl<<" 4.Cine "<<endl<<" 5.Gastronomía "<<endl<<" 6.Ordenadores "<<endl<<" 7.JuegosDeRol "<<endl<<" 8.Modelismo "<<endl<<" 9.Perros "<<endl;
       for(int j=0; j<3 ;j++){
           cin>>l.NC[l.numero_de_clientes].aficiones[j];
       }
       l.numero_de_clientes++;

}
bool buscar(string nomb,int& i,TListaClientes lista){
  bool a=false;
  for(int j=0;j<lista.numero_de_clientes;j++){
   if(nomb==lista.NC[j].nombre){
       a=true;
       i=j;
   }
  }
  return a;
}
void mostrar(int s,TListaClientes l){
   cout<<endl<<"Nombre: "<<l.NC[s].nombre;
   cout<<endl<<"Sexo: "<<l.NC[s].sexo;
   cout<<endl<<"Edad: "<<l.NC[s].edad;
   cout<<endl<<"Aficiones: "<<endl;
   for(int i=0; i<3; i++){
       mosafi(i,s,l);
   }
}
void mosafi(int af,int s,TListaClientes lista){
   switch(lista.NC[s].aficiones[af]){
     case 1: cout<<"Lectura"<<endl;
     break;
     case 2: cout<<"Viajes"<<endl;
     break;
     case 3: cout<<"Deportes"<<endl;
     break;
     case 4: cout<<"Cine"<<endl;
     break;
     case 5: cout<<"Gastronomía"<<endl;
     break;
     case 6: cout<<"Ordenadores"<<endl;
     break;
     case 7: cout<<"JuegosDeRol"<<endl;
     break;
     case 8: cout<<"Modelismo"<<endl;
     break;
     case 9: cout<<"Perros"<<endl;
   }
}
bool borrar(string n,TListaClientes &l){
   int i;
   bool a;
   a=buscar(n,i,l);
   if(a){
       for(int j=i; j<l.numero_de_clientes ; j++){
           l.NC[j]=l.NC[j+1];
       }
       l.numero_de_clientes--;
   }
   return a;
}
bool casar(string n,TListaClientes &lista){
   bool a,b;
   int i,j,parej;

   a=buscar(n,i,lista);
   if (a){
      a=false;
      for(j=0; j<lista.numero_de_clientes || a==false ; j++){
       if (lista.NC[j].nombre!=n){
         if(afic_iguales(i,j,lista)) parej=j;a=true ;
       }
      }
   }
 return a;
}
bool afic_iguales(int i, int &j, TListaClientes l){
  bool b=true;
  for(int k=0; k<3 ;k++){
   for(int y=0; y<3 && b==true; y++){
       if(l.NC[i].aficiones[k]!=l.NC[j].aficiones[y]) {
           b=false;
       }
   }
  }
  return b;
}

rir3760

Cita de: chicainge en 13 Septiembre 2014, 16:40 PMtengo un problema con esta programa en el getline() este al introducirle mas de un caracter me mete en un bucle he probado a introducirle un cin.ignore o un cin.get() pero nada sigue teniendo problemas el getline(), alguien que sepa su funcionamiento y me explique que le pasa
Si en un programa se tiene (como es tu caso) un uso intercalado del operador ">>" y getline se presentaran problemas debido a que el operador ">>" solo consume los caracteres validos para la conversión en turno, el primer carácter invalido usualmente es el avance de linea o '\n'. A continuación la función getline procesa el carácter restante (el '\n') como una linea en blanco.

El mentado problema en la función main:
Código (cpp) [Seleccionar]
while( c != 'E'){
   cin >> c; // Al menos el '\n' se mantiene en el bufer ...
   switch(toupper(c)){
   // ...
   case 'B' :
      cout<<"Nombre buscado: ";
      getline(cin, n); // ... lee '\n' como una linea en blanco
      buscar(n,nr,lista);
      mostrar(nr,lista);
      break;
   case 'C' :
      cout<<"Nombre del cliente que desea borrar: ";
      getline(cin, n);  // ... lee '\n' como una linea en blanco


Para solucionarlo debes descartar el resto de la linea justo después del uso de ">>" y antes de la llamada a getline, opciones para ello son las funciones ignore y sync, un ejemplo de la primera donde se utiliza un bucle para leer una linea y un carácter:
Código (cpp) [Seleccionar]
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

#include <string>
using std::string;

#include <limits>
using std::numeric_limits;

int main()
{
   string linea;
   char ch;
   
   do {
      cout << "Frase: ";
      getline(cin, linea);
     
      cout << "Continuar? (S/N) ";
      cin >> ch;
      cin.ignore(numeric_limits<int>::max(), '\n');
   }while (ch == 's' || ch == 'S');
   
   return 0;
}


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

chicainge

ajaaa!! muchisimas gracias:))