How to deal with the use of getline () in a for (;;)?

1

I am storing the names of authors of books in a string vector.

     for(int i = 0; i<qt; i++)
        {
            cin >> nome;
            NOME[i] = nome;
        }

But I want to have the full name, first name and last name, so I thought of doing:

for(int i = 0; i<qt; i++)
        {
            getline(cin,nome);
            NOME[i] = nome;
        }

But, if qt == 2 for example, it will only read the name of an author, type "Flavio melo", after reading the first it will not read the second name.

Then I tried:

for(int i = 0; i<qt; i++)
        {
            LIMPA_BUFFER;
            getline(cin,nome);
            NOME[i] = nome;
        }

Where LIMPA_BUFFER; does cin.ignore(INT_MAX, '\n') . But still, it will read the name of the first author, the second, and then jump to a third author! (even in the case where qt == 2 ). When I print the vector with the names of the authors, it does not print any names.

How do I read the full names, store in the vector, and display the names usually using getline() ?

Here is the complete TAD implementation code:

My problem is in case 1: and method inserir_autor()

# include <iostream>
# include <stdio.h>
# include <stdlib.h>
# include <climits>
# include <cassert>

#define TAM_max 10
#define LIMPA_BUFFER    cin.ignore(INT_MAX, '\n')

using namespace std;

class Livro
{
private:
    friend class Data;

    string *Autores;
    string Titulo;
    int aux = 0;

public:

    Livro ()
    {
        Autores = new string [TAM_max+1];
    }

    /// Titulo do livro
    void titulo_livro (string titulo)
    {
        Titulo = titulo;
    }

    /// Adiciona os autores principais
    void inserir_autor (string* &nome_aut, int qt)
    {
        aux = qt;
        for(int i = 0; i<qt; i++)
        {
            Autores[i] = nome_aut[i];
        }

    }

    /// Adiciona mais autores
    bool inserir_mais_autores (string novo_aut)
    {
        if(aux < TAM_max)
        {
            Autores[aux] = novo_aut;
            aux++;
            return true;
        }
        else
            return false;

    }

    /// Remove um autor
    bool remover_autor (string autor_remv)
    {
        for(int i = 0; i<TAM_max ; i++)
        {
            if(Autores[i] == autor_remv)
            {
                for(int j=i; j<TAM_max; j++)
                {
                    Autores[j] = Autores[j+1];
                }
                aux--;
                return true;
            }
        }
        return false;
    }

    /// Altera o titulo
    void altera_titulo (string novo_titulo)
    {
        Titulo = novo_titulo;
        cout << "\n Seu novo Titulo: " << Titulo << endl;
    }



    /// Altera autor
    bool altera_autor (string autor, string novo_autor)
    {
        for(int i = 0 ; i<TAM_max; i++)
        {
            if(Autores[i] == autor)
            {
                Autores[i] = novo_autor;
                return true;
            }
        }
        return false;

    }

    /// Imprime os dados do livro
    void imprime_livro()
    {
        cout << "\t Dados do livro:" << "\n" << endl;
        cout << "\n Titulo: " << Titulo << endl;
        cout << "\n Autores: \n" << endl;
        for(int i = 0 ; Autores[i] != "" ; i++)
        {
            cout<< "[" << i+1 << "] = " << Autores[i] << "\n" <<endl;
        }
    }

};


class Data
{
private:
    friend class Livro;
    int DIA = 0, MES = 0, ANO = 0;

public:

    bool verifica_data(int dia, int mes, int ano)
    {
        if( (dia >= 1 && dia <= 31) && (mes >= 1 && mes <= 12) ) //verifica se os numeros sao validos)
        {
            if ((dia == 29 && mes == 2) && ((ano % 4) == 0 && (ano % 100)!= 0 || (ano % 400) == 0)) //verifica se o ano e bissexto
            {
                return true;
            }
            if (dia <= 28 && mes == 2) //verifica o mes de fevereiro
            {
                return true;
            }
            if ((dia <= 30) && (mes == 4 || mes == 6 || mes == 9 || mes == 11)) //verifica os meses de 30 dias
            {
                return true;
            }
            if ((dia <=31) && (mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes ==8 || mes == 10 || mes == 12)) //verifica os meses de 31 dias
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    void inserir_data(int dia, int mes, int ano)
    {
        DIA = dia;
        MES = mes;
        ANO = ano;
    }

    void imprime_data()
    {
        cout << " Data de Publicacao: " << "\n" << endl;
        cout << DIA << "/" << MES << "/" << ANO << "\n" <<endl;
    }

};

int main()
{

    Livro L;
    Data D;

menu:

    cout << "\n" << endl;
    system("cls");

    int op=0;
    cout << "\tEstante Virtual\n" << endl;
    cout << "1 - Cadastrar livro" << endl;
    cout << "2 - Imprimir dados" << endl;
    cout << "3 - Remover um autor(a)" << endl;
    cout << "4 - Inserir novo autor(a)" << endl;
    cout << "5 - Alterar nome do livro" << endl;
    cout << "6 - Alterar data de publicacao" << endl;
    cout << "7 - Alterar nome de um autor(a)" << endl;
    cout << "0 - Encerrar programa"<< "\n"  << endl;

    cin >> op;
    switch (op)
    {
    case 0:
        return 0;

    case 1:
        {
            system("cls");

            int qt = 0;
            int dia = 0, mes = 0, ano = 0;
            bool valida_data;
            string titulo;

            cout << " Nome do livro: \n" << endl;
            LIMPA_BUFFER;
            getline(cin, titulo);
            L.titulo_livro(titulo);

            cout << "\n Informe a quantidade de autores: \n" << endl;
            cin >> qt;

            while(qt > 0)
            {
                if(qt > 0 && qt <= TAM_max)
                    break;
                else
                {
                    cout << "\n Informe no minimo 1 e no maximo 10 autores" << endl;
                    cin >> qt;
                }

            }

            cout << "\n Informe seus nomes: \n" << endl;
            string *NOME = new string [TAM_max+1];
            string nome;

            for(int i = 0; i<qt; i++)
            {
                cin >> nome;
                NOME[i] = nome;
            }


            L.inserir_autor(NOME,qt);

            cout << "\n Data de publicacao: \n" << endl;
            cin >> dia >> mes >> ano;
            valida_data = D.verifica_data(dia,mes,ano);
            if(valida_data == true)
            {
                D.inserir_data(dia,mes,ano);
            }
            else
            {
                while(valida_data == false) //Enquanto não for válido, então...
                {
                    cout << "\n Data invalida! \n\n Informe uma data de publicacao valida: \n" << endl;
                    cin >> dia >> mes >> ano;
                    valida_data = D.verifica_data(dia,mes,ano);
                }
                D.inserir_data(dia,mes,ano);
            }

            system("cls");
            cout << " Cadastro efetuado com sucesso! \n" << endl;
            system("pause");
            break;
        }

    case 2:
        {
            system("cls");
            L.imprime_livro();
            D.imprime_data();

            system("pause");
            break;
        }

    case 3:
        {
            system("cls");
            string autor_remv;

            cout << " Informe o autor que deseja remover: " << endl;
            cin >> autor_remv;

            bool valor = L.remover_autor(autor_remv);
            if(valor == true)
                cout << "\n Autor removido com sucesso! \n" << endl;
            else
                cout << "\n Autor inexistente! \n" << endl;

            system("pause");
            break;
        }

    case 4:
        {
            system("cls");
            string autor;
            bool valor;

            cout << " Informe o nome do autor: " << endl;
            cin >> autor;

            valor = L.inserir_mais_autores(autor);
            if(valor == true)
                cout << "\n Autor cadastrado com sucesso! \n" << endl;
            else
                cout << "\n Limite maximo de autores atingido! \n" << endl;

            system("pause");
            break;
        }

    case 5:
        {
            system("cls");
            string novo_titulo;

            cout << " Informe o novo nome para o livro: \n" << endl;
            LIMPA_BUFFER;
            getline(cin, novo_titulo);
            L.altera_titulo(novo_titulo);
            cout << "\n Titulo alterado com sucesso! \n" << endl;

            system("pause");
            break;

        }

    case 6:
        {
            system("cls");
            int dia = 0, mes = 0, ano = 0;

            cout << " Informe a nova data: \n" << endl;
            LIMPA_BUFFER;
            cin >> dia >> mes >> ano;
            D.inserir_data(dia,mes,ano);

            cout << "\n Data alterada com sucesso! \n" << endl;

            system("pause");
            break;

        }

    case 7:
        {
            system("cls");
            string autor, novo_autor;
            bool valor;

            cout << " Informe o nome do autor que sera modificado:" << endl;
            cin >> autor;

            cout << "\n Informe o novo nome:" << endl;
            cin >> novo_autor;

            valor = L.altera_autor(autor, novo_autor);

            if(valor == true)
                cout << "\n Autor renomeado com sucesso! \n\n" << endl;
            else
                cout << "\n '" << autor << "' nao foi encontrado! \n\n" << endl;

            system("pause");
            break;

        }
    }
    goto menu;
    return 0;
}
    
asked by anonymous 04.11.2015 / 14:31

1 answer

2

One possible solution is, as you presented in your question, by using the getline function. The replacement in this case is almost immediate. You just have to ensure that the cin buffer is cleared before you use the getline function. Your code would look like this:

case 1:
    {
        system("cls");

        //(...)

        cout << "\n Informe seus nomes: \n" << endl;
        string *NOME = new string [TAM_max+1];
        string nome;

        //limpar buffer
        cin.clear();
        cin.ignore(INT_MAX, '\n');

        for(int i = 0; i<qt; i++)
        {
            //cin >> nome;
            getline(cin, nome);
            NOME[i] = nome;
        }

        L.inserir_autor(NOME,qt);

        //(...)

        system("cls");
        cout << " Cadastro efetuado com sucesso! \n" << endl;
        system("pause");
        break;
    }

As a final comment, I suggested using the vector class instead of using pointers to the class string. In your case there is no advantage, on the contrary, it is giving rise to a "memory leak":

Whenever you register the names of the authors of the books you are allocating memory that is never released:

  string *NOME = new string [TAM_max+1];
    
08.11.2015 / 11:16