Doubts about cleaning buffer in C ++

1

I have a function that reads a name, if the name is new it saves it in a data structure and if the name is repeated it asks for the name again. (I have other functions similar to this, but this is the only one that uses getline (cin, variable)

void anombre(){
    cout << "Nombre: ";
    cin.ignore();
    getline(cin, nombre);
    if(!agenda.vnombre(nombre))
        anombre();
}

My problem is that this function only works once; Assuming that I have already stored the name "Mariana" when calling the function, the program would look like this:

Nombre: Mariana
Nombre: Mariana
Telefono: 

Being Phone: the message of the following function to request the data, that is, anombre () only denied the name repeated once and went to the next function. Passing this stores an empty string and that goes to my structure.

The agenda.vname (name) function is as follows:

bool vnombre(string& n){
    for(int i = 0; i < tamano(); ++i){
        if(n == contactos[i].nombre) return false;
    }
    return true;
}

The other functions are basically the same, only the type of data that you are going to check changes: contacts [i] .phone, contacts [i] .mail, etc.

What is my mistake? I understand that it is part of cleaning the cin buffer for this to work properly. (This does not happen with the other functions to request data such as telephone, email, age, etc.).

    
asked by akko 09.01.2017 в 08:27
source

1 answer

2

The signature of the cin.ignore() function is:

istream& ignore (streamsize n = 1, int delim = EOF);

That is, if you make the call:

cin.ignore();

You are removing at most one character from the buffer. This is far from the objective that you intend to clean the input buffer. One of the most common ways to clean the buffer is

std::cin.ignore(std::numeric_limits<size_t>::max());

std::numeric_limits<size_t>::max() indicates the highest number for type size_t , an alias that in 32 bits is usually equivalent to unsigned int . The previous instruction, in summary, tries to discard all the contents of the input buffer.

On the other hand, the function getline is responsible for eliminating the delimiter of the input buffer. If parts of a clean buffer, the call to getline will leave the buffer equally clean. That is, calling the function ignore recursively is not necessary and may even be counterproductive.

Try the following:

void anombre(){
  cin.ignore(numeric_limits<size_t>::max());
  do
  {
    cout << "Nombre: ";
    getline(cin, nombre);
  } while (!agenda.vnombre(nombre));
}

You save recursive calls (which are not necessary) and avoid cleaning the buffer when it's not necessary.

    
answered by 09.01.2017 / 09:29
source