JMU
Input/Output in C++
An Introduction


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Motivation
Getting Started
Stream Objects
Using the Console
Using the Console (cont.)
Opening and Closing Streams
I/O Modes
I/O Modes (cont.)
Testing the State of a Stream

int bad() Returns non-zero if the previous I/O operation failed and data were lost
int good() Returns non-zero if the previous I/O operation succeeded
int eof() Returns non-zero if previous read succeeded and the stream is empty
int fail() Returns non-zero if previous I/O operation failed

Writing ASCII Streams
Reading ASCII Streams
Some Other Useful Methods

get Extract a single character or a string (including whitespace)
getline Extract a full "line" of characters
ignore Discards a given number of characters
putback Inserts a character back into the input stream after it has been read

An Example

A File Splitter

cppexamples/io/FileSplitter.cpp
        /**
 * Splits the file test.txt into 10 or fewer pieces,
 * each containing 500 characters (except the last 
 * piece which may be smaller)
 *
 * @author  Prof. David Bernstein, James Madison University
 */

#include <iostream>
#include <fstream>
using namespace std;

/**
 * fileSplit
 *
 * Reads a given file and splits it into pieces
 * containing a given number of characters
 *
 * @param inFileName[]  The name of the input file
 * @param n             The size of each piece
 */
void fileSplit(char inFileName[], int n) {
  char c;
  char outFileName[6] = { 'p', 'a', 'r', 't', '?', '\0' };
  ifstream inFile;
  int characters, fileNumber;
  ofstream outFile;

  // Open the input file
  //
  inFile.open(inFileName, (ios::in));
  if (inFile.fail()) {
    cout << "\tUnable to open input file!\n";
    return;
  }

  // Initialize
  //
  characters = 0;
  fileNumber = 0;

  // Read in every character from the input file
  // (Note: Don't use << since it skips leading whitespace)
  //
  while (!inFile.eof()) {
    inFile.get(c);
    characters++;

    // Close the previous file if necessary
    //
    if (characters > n) {
      outFile.close();
      fileNumber++;
      characters = 1;

      if (fileNumber >= 10) {
        cout << "\tToo many pieces!\n";
        return;
      }
    }

    // Open the next file if necessary
    //
    if (characters == 1) {
      // Put the ASCII code into the output file name
      outFileName[4] = (fileNumber + 48);
      outFile.open(outFileName, ios::out);
      if (outFile.fail()) {
        cout << "\tUnable to open output file " << fileNumber << "!\n";
        return;
      }
    }

    outFile.put(c);
  }

  inFile.close();
  outFile.close();
}

/**
 * main
 *
 * The entry point of the application
 */
int main(void) {
  fileSplit("test.txt", 500);

  return 1;
}
        
Formatted ASCII I/O
Using Format Bits
Using Format Bits (cont.)
An Example

    using namespace std;

    cout.setf(ios::hex | ios::showbase | ios::uppercase );
    cout << 1023;
    

The Result

    0x3FF
    

Using Manipulators
Using Manipulators (cont.)
An Example

    #include <iostream>
    #include <iomanip>

    using namespace std;

    int    n;

    n = 12;

    cout << setw(5) << n << "\n";
    

The Result

Three spaces and then the two-digit number 12

Reading and Writing Binary Streams
Portability of Binary Files
Random/Direct Access
Random/Direct Access (cont.)
An Example

    inputFile.seekg(300);
    

Explained

Moves the read head to byte number 300

Random/Direct Access (cont.)
Another Example

    inputFile.seekg(-100, ios::end);
    inputFile.seekg(10, ios::cur);
    

Explained

First moves the read head to the position 100 bytes prior to the end of the file and then moves it 10 bytes forward from that position

Random/Direct Access (cont.)