https://rentry.org/PPP2_p366

// Code derived from Stroustrup's PPP2 book
// § 10.10 A standard input loop
//  -and beginning on p 366

#include <iostream>
#include <stdexcept>
#include <string>

using namespace std;

void error(const string s) { throw runtime_error(s); }
void error(const string s1, const string s2) { error(s1 + s2); }

//------------------------------------------------------------------------------

typedef int My_type;

void end_of_loop(istream& ist, char term, const string& message)
{
  if (ist.fail()) {  // use term as terminator and/or separator
    ist.clear();

    char ch;
    if (ist >> ch && ch == term)
      return;  // all is fine

    error(message);
  }
}

void input_loop_v1(istream& ist)
{
  for (My_type var; ist >> var;) {  // read until end of file
    // maybe check that var is valid
    // . . . do something with var . . .
  }

  // we can rarely recover from bad; don’t try unless you really have to:
  if (ist.bad())
    error("bad input stream");

  if (ist.fail()) {
    // was it an acceptable terminator?
  }

  // carry on: we found end of file
}

void input_loop_v2(istream& ist)
{
  for (My_type var; ist >> var;) {  // read until end of file
    // maybe check that var is valid
    // . . . do something with var . . .
  }

  if (ist.fail()) {  // use '|' as terminator and/or separator
    ist.clear();

    char ch;
    if (! (ist >> ch && ch == '|'))
      error("bad termination of input");
  }

  // carry on: we found end of file or a terminator
}

void input_loop_v3(istream& ist)
{
  for (My_type var; ist >> var;) {  // read until end of file
    // maybe check that var is valid
    // . . . do something with var . . .
  }

  end_of_loop(ist, '|', "bad termination of file");  // test if we can continue

  // carry on: we found end of file or a terminator
}

int main()
try {
  istream& ist{cin};

  // make ist throw if it goes bad (so we no longer need to test for that state)
  ist.exceptions(ist.exceptions() | ios_base::badbit);

  input_loop_v1(ist);
  input_loop_v2(ist);
  input_loop_v3(ist);  // <- this version would be our 'standard loop' choice

} catch (exception& e) {
  cerr << "error: " << e.what() << '\n';
  return 1;

} catch (...) {
  cerr << "Oops: unknown exception!\n";
  return 2;
}

build & run:

g++ -std=c++20 -O2 -Wall -pedantic ./ch_10/main_p366.cpp && ./a.out

PrevUpNext

Edit
Pub: 07 Apr 2023 22:33 UTC
Edit: 03 May 2023 10:10 UTC
Views: 625