[C con Clase] Duda sobre cin.getline

Steven Davidson srd4121 en njit.edu
Lun Abr 4 01:11:07 CEST 2011


Hola Jovanny,

On 4/3/2011 5:22 PM, Jovanny wrote:
> Hola, mi duda es la siguiente:
>
> En la IDE Code :: Blocks 10.05, al usar la función cin.getline no me
> deja ingresar la cadena de caracteres:
>

Te comento algunas cosas que he visto en este código fuente.

> #include<iostream>
> #include<cstring>

Debes incluir <cstdlib>, porque usas la función 'system()'.

> #define TAM 64
>

No aconsejo definir constantes simbólicas, sino del lenguaje de C++; es 
decir,

const int TAM = 64;

Además, como vas a usar esta constante en la clase 'Libreria', tiene más 
lógica que pertenezca a ella como miembro.

> using std :: cin;
> using std :: cout;
>

También tienes que indicar que vas a usar 'endl':

using std::endl;

> class Libreria
> {
>     public:
>            Libreria()
>            {
>               strcpy(title, "Libreria IPN");

Sugiero asignar una cadena válida a 'nombreLibro', ya que la idea es que 
el objeto instanciado esté en un estado correcto; para esto mismo sirve 
el constructor. Por ejemplo,

nombreLibro[0] = 0;  // Cadena nula

>            }
>            void titulo()

Sugiero indicar que esta función miembro es constante, ya que no tenemos 
intención de que modifique el estado de este objeto. Esto es,

void titulo() const
{
   ...
}

>            {
>               system("cls");
>               cout<<  title<<  endl<<  endl;
>            }
>            void pedir();
>

Define aquí la constante 'TAM':

static const int TAM = 64;

Necesitas 'static' para que no se creen constantes en cada objeto 
instanciado.

>     private:
>            char title[TAM];
>            char nombreLibro[TAM];
>
> }objLibreria;
>

Aquí, instancias un objeto global. No es aconsejable hacer esto, por lo 
que deberías optar por instanciar el objeto localmente.

> void Libreria :: pedir()
> {
>     cout<<  "Ingresa el titulo del libro: ";
>     cin.getline(nombreLibro, TAM);  // He aquí el problema

No hay ningún error.

> }
>
> int main()
> {
>     objLibreria.titulo();
>     objLibreria.pedir();
>
>     return 0;
> }
>
> Al ejecutar este código, no me deja ingresar la cadena de caracteres
> (nombre del libro) y aparece el mensaje de que se ha finalizado el
> programa.
>
> Quisiera saber por qué ocurre eso, o si es que cometí algún error; en
> el caso de que el programa pidiera el nombre del autor, editorial,
> etc, usando la misma funcion cin.getline(), se salta el titulo pero
> si deja ingresar el autor o editorial.
>

He probado este código y no he tenido ningún problema. Lo único que 
puedo pensar es que es posible que hayas usado 'cin' previamente para 
leer un número, pero se ha quedado en el búfer del canal otros 
caracteres escritos que no se podían convertir a un número. 
Posteriormente, intentas leer una cadena y como hay caracteres en el 
canal, el programa no los pide, sino que los extrae directamente del 
canal. Por ejemplo,

int num;
char cad[10];

cin >> num;
cin.getline( cad, 10 );

El usuario escribe:
123[ENTER]

El canal contiene: "123\n"

Después de leer y convertir la cadena a un entero para guardarlo en 
'num', el canal contiene: "\n".

Al conseguir la siguiente línea con 'getline()', esta función miembro 
lee el siguiente carácter que es '\n' - fin de línea - por lo que 
detiene la lectura.

Desde el punto de vista del usuario, el programa no le ha dejado 
introducir una cadena; se ha saltado tal lectura.

Una solución es invocar 'cin.get()' para que extraiga ese carácter de 
fin-de-línea después de la lectura del número.


Si no has tenido ninguna lectura previa de números, entonces por alguna 
razón hay un error. Es posible que el error sea del canal. Alguna 
operación del canal anterior ha provocado un error por lo que el 
comportamiento de las operaciones posteriores se basa en ignorar tales 
operaciones - debido al error interno del canal. Para descubrir si hay 
un fallo interno en el canal, invoca la función miembro 'fail()'.


Espero que esto te ayude.

Steven





Más información sobre la lista de distribución Cconclase