Cancella buffer di input in C++

Jinku Hu 12 ottobre 2023
Cancella buffer di input in C++

Questo articolo illustrerà più metodi su come cancellare il buffer di input in C++.

Usa la funzione std::cin::ignore per cancellare il buffer di input in C++

ignore è una funzione incorporata dell’oggetto std::cin e può essere usato per estrarre e scartare caratteri dal flusso di input fino al delimitatore specificato. Prima di discutere il comportamento della funzione cin::ignore, si dovrebbe notare che i flussi di input e output standard come cin / cout sono bufferizzati, il che significa che c’è una certa contabilità tra le scritture / letture dell’utente e l’effettivo stato del buffer nel kernel del sistema operativo. Questo buffer è gestito dalla libreria C++ stessa e il suo scopo è rendere più efficienti le richieste di lettura / scrittura. Si noti che la richiesta di servizi del sistema operativo per ogni byte sarebbe un uso abbastanza inefficiente delle risorse della CPU, quindi il buffer intermedio viene utilizzato per accumulare alcune richieste e quindi chiamare il sistema operativo con una singola richiesta.

Quindi, cin::ignore può scartare i byte rimasti nel buffer che possono essere letti accidentalmente quando ci sono chiamate consecutive. Il seguente codice di esempio è progettato per dimostrare più chiaramente il comportamento di ignore. Abbiamo implementato un bucle infinito while che legge tre numeri interi dal flusso cin e li memorizza nelle variabili corrispondenti. Gli interi vengono stampati in cout e quindi la routine viene eseguita all’iterazione successiva. Si noti che l’utente può fornire più di tre numeri interi nella prima iterazione. In tal caso, il codice prima di cin.ignore ne memorizzerebbe solo 3, mentre altri esisteranno ancora in un buffer intermedio. Ora, se cin.ignore non viene chiamato con i parametri dati, la riga successiva dell’iterazione cin >> leggerà il resto dell’input e si verificherà il comportamento incoerente. La chiamata cin.ignore può essere utilizzata in tali scenari per scartare l’input fino a quando il carattere dato non viene incontrato. In questo caso, abbiamo specificato un nuovo carattere di riga che è generalmente usato per bufferizzare il flusso cin.

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  while (true) {
    int i1, i2, i3;
    cout << "Type space separated numbers: " << endl;
    cin >> i1 >> i2 >> i3;
    if (i1 == 0) exit(EXIT_SUCCESS);
    cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    cout << i1 << "; " << i2 << "; " << i3 << endl;
  }

  return EXIT_SUCCESS;
}

Output (con l’input dell’utente di esempio):

Type space separated numbers:
12 32 54
12; 32; 54

In alternativa, possiamo implementare un altro codice di esempio che accetta due stringhe divise per delimitatore di caratteri di spazio. In questo scenario, è possibile che l’utente fornisca più di 2 nomi che costringerebbero questo codice a eliminare tutte le iniziali dopo 2 stringhe separate da spazi. Se ci sono solo un nome e uno spazio nell’input dell’utente, allora un carattere di nuova riga, che termina sempre l’input cin, verrà memorizzato come seconda iniziale. Quest’ultimo comportamento può essere dimostrato aggiungendo l’output di un singolo carattere dopo l’istruzione << name << surname.

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  char name, surname;
  cout << "Type your name and surname: ";
  name = cin.get();
  cin.ignore(numeric_limits<std::streamsize>::max(), ' ');
  surname = cin.get();

  cout << "Your initials are: " << name << surname << endl;

  return EXIT_SUCCESS;
}

Output (con l’input dell’utente di esempio):

Type your name and surname: Lama Lime
Your initials are: LL
``
Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Articolo correlato - C++ IO