Advanced Introduction to C++, Scientific Computing and Machine Learning




Claudius Gros, WS 2019/20

Institut für theoretische Physik
Goethe-University Frankfurt a.M.

Streams & Files

manipulating the console output stream

Copy Copy to clipboad
Downlaod Download
#include <iostream>         // std IO
#include <stdio.h>          // printf()
#include <math.h>           // abs()
#include <stdlib.h>         // exit()
 
using namespace std;
 
// --- --------------------
// --- console canvas class
// --- --------------------
 
class Canvas                    
{
private:
 static const int nColors = 6;
 string forwardColors[6], backwardColors[6];   // ANSI colors
 int dimX, dimY;              // dimensions of drawing panel
 int x, y;                    // current cursor position;
public:
 Canvas()                     // overwriting the default constructor
   {
   cout << "(Canvas): wrong constructor\n"; 
   exit(EXIT_FAILURE);        // exit(0) for success
   }   
 Canvas(int dimX, int dimY)   // regular constructor (to be used)
   {
   this->dimX = dimX;
   this->dimY = dimY;
   forwardColors[0] = "\x1b[30m"; backwardColors[0] = "\x1b[40m";  // black
   forwardColors[1] = "\x1b[31m"; backwardColors[1] = "\x1b[41m";  // red
   forwardColors[2] = "\x1b[32m"; backwardColors[2] = "\x1b[42m";  // green
   forwardColors[3] = "\x1b[33m"; backwardColors[3] = "\x1b[43m";  // yellow
   forwardColors[4] = "\x1b[34m"; backwardColors[4] = "\x1b[44m";  // blue
   forwardColors[5] = "\x1b[37m"; backwardColors[5] = "\x1b[47m";  // white
   x = 0;
   y = 0;
   }
 
 void moveCursor(int deltaX, int deltaY)
   {
   static const string first("\x1b[");
   static const string plusY("A");
   static const string minusY("B");
   static const string plusX("C");
   static const string minusX("D");
   char strDeltaX[50];
   char strDeltaY[50];
   string escapeCharX, escapeCharY;
   sprintf(strDeltaX, "%d",(deltaX>0)?deltaX:(-deltaX)); // write to string 
   sprintf(strDeltaY, "%d",(deltaY>0)?deltaY:(-deltaY)); 
//
   if (deltaX>0)
     escapeCharX = first + strDeltaX + plusX;
   else
     escapeCharX = first + strDeltaX + minusX;
//
   if (deltaY>0)
     escapeCharY = first + strDeltaY + plusY;
   else
     escapeCharY = first + strDeltaY + minusY;
//
   if (deltaX!=0)
     cout << escapeCharX;                // stream control sequence
   if (deltaY!=0)
     cout << escapeCharY;   
   x = x + deltaX;
   y = y + deltaY;
   }
 
 void clearCanvas()
   {
   moveCursor(-x,dimY-y); 
   for (int i=0;i<dimY;i++)
     {
     for (int j=0;j<dimX;j++)
       {
       cout << " ";
       x++;
       }
     moveCursor(-x,-1); 
     }
   }      
 
 void drawBorder()
   {
   moveCursor(-x,dimY-y); 
   cout << backwardColors[4];
   for (int j=0;j<dimX;j++)
     { cout << " "; x++; }
   for (int i=1;i<dimY;i++)
     { moveCursor(-1,-1); cout << " "; x++;}
//
   moveCursor(-x,dimY-y); 
   for (int i=1;i<dimY;i++)
     { cout << " "; x++; moveCursor(-1,-1);}
   for (int j=0;j<dimX;j++)
     { cout << " "; x++; }
//
   cout << "\x1b[0m";          // clear all formatting, if any
   }
 
 void colorText(string text, int color, int xPos, int yPos)
   {
   moveCursor(-x,-y);        // got to lower left corner
   moveCursor(xPos,yPos);    // writing here
   cout << forwardColors[color];
   cout << text ;
   x += text.length();
   cout << "\x1b[0m";          // clear all formatting, if any
   }
 
};        // end of Canvas class
 
// --- ----
// --- main
// --- ----
 
int main()
 {
 cout << "       "; 
//
 Canvas *myCanvas = new Canvas(40,20);
 myCanvas->clearCanvas();
 myCanvas->drawBorder();
 myCanvas->colorText("this is a canvas,",1,5,13);
 myCanvas->colorText("which can be used for",2,5,11);
 myCanvas->colorText("simple animations",3,5,9);
 
 myCanvas->colorText(" ",0,0,0);  // goto orgin
 cout << "\x1b[0m";            // clear all formatting, if any
 
 return 0;
 }

file streams

Copy Copy to clipboad
Downlaod Download
#include <iostream>     // standard IO
#include <fstream>      // file streams
#include <math.h>
using namespace std;
 
void printData(ofstream &myStream, string outputString) // by reference
{
 myStream << "# (printData): " + outputString;
 double radius, phi, x, y;
 for (int i=1;i<100;i++)
    {
    phi = i*M_PI*4.00/100.0;
    radius = 1.0 + i*2.0/100.0;   // linear spiral
    x = radius*cos(phi);
    y = radius*sin(phi);
    myStream << x << " " << y << endl;
    }
}
 
int main () 
{
 ofstream myOutput;
 myOutput.open("test.dat",ios::out);
 myOutput.setf(ios::fixed,ios::floatfield);  // for formated output 
 myOutput.precision(2);                      // floating point precision
 
 myOutput << "# the hashtag is for comments in data files\n";
//
 printData(myOutput, "data output should bed done in the respective utilities\n");
//
 myOutput.close();
//
 string line;
  ifstream myInput ("test.dat");
  if (myInput.is_open())            // found and opened?
    {
    while ( getline(myInput,line) )
      cout << line << '\n';
    myInput.close();
    }
  else 
    cout << "(main) unable to open file\n";
//
 return 1;
}

string streams | reading numerical data

Copy Copy to clipboad
Downlaod Download
#include <iostream>     // standard IO
#include <fstream>      // file streams
#include <sstream>      // string streams
#include <stdio.h>      // printf
#include <math.h>
using namespace std;
 
void generateData(string fileName)
{
 ofstream myStream;
 myStream.open(fileName.c_str(),ios::out);
 myStream.setf(ios::fixed,ios::floatfield);  // for formated output 
 myStream.precision(4);                      // alternatively use sprintf()
 myStream << "# a quadratic spiral\n";
 myStream << "# x  y\n";
//
 double radius, phi, x, y;
 int nData = 500;
 for (int i=1;i<nData;i++)
    {
    phi = i*M_PI*6.00/nData;
    radius = 0.1 + i*i*2.0/(nData*nData);   // quadratic spiral
    x = radius*cos(phi);
    y = radius*sin(phi);
    myStream << x << " " << y << endl;
    }
}
 
int main()
{
 string fileName = "test.dat";
 generateData(fileName);
//
// --- string stream example
//
 int aaa, bbb;
 stringstream ss;
 ss << 100 << ' ' << 200; // streaming   to ss
 ss >> aaa >> bbb;              // streaming from ss
//
 printf("\n");
 printf("aaa: %d and bbb: %d\n",aaa,bbb);
 printf("\n\n");
//
// --- extracting numbers via string stream
//
 string line;
  ifstream myInput(fileName.c_str()); // input file stream
  if (myInput.is_open())              // found and opened?
    {
    while ( getline(myInput,line) )
      {
      istringstream inputSS(line);    // line loaded in buffer
      double a, b;
      if (inputSS >> a >> b)          // line containing two numbers?
        printf("(main) %6.3f %6.3f\n",a,b);
      else
        cout << line << '\n';
      } 
    myInput.close();
    }
  else
    cout << "(main) unable to open file\n";
//
 return 1;
}

controlling the input stream

Copy Copy to clipboad
Downlaod Download
#include <iostream>     // standard IO
#include <fstream>      // file streams
#include <limits.h>     // INT_MAX, etc
#include <stdio.h>      // printf
#include <stdlib.h>     // srand, rand 
using namespace std;
 
/* *** ************ *** */
/* *** generateData *** */
/* *** ************ *** */
 
void generateData(string fileName)
{
 ofstream myStream;
 myStream.open(fileName.c_str(),ios::out);
 myStream.setf(ios::fixed,ios::floatfield);  // for formated output 
 myStream.precision(4);                      // alternatively use sprintf()
 myStream << "# a 2D random walk\n";
 myStream << "# x  y\n";
//
 int nData = 150;
 double probability, x=0, y=0;
//
 for (int i=1;i<nData;i++)
   {
    myStream << x << " " << y << endl;
    probability = rand()/(double)RAND_MAX;
    x += probability-0.5;
    probability = rand()/(double)RAND_MAX;
    y += probability-0.5;
   }
}
 
/* *** **** *** */
/* *** main *** */
/* *** **** *** */
 
int main()
{
 srand(time(NULL));   // Initialize once at program startup.
 string fileName = "test.dat";
 generateData(fileName);
//
// --- extracting numbers directly
//
 string line;
 const char commentChar = '#';
 ifstream myInput(fileName.c_str()); // input file stream
 char inChar = myInput.peek();       // peak first char of file
 while (inChar==commentChar)         // skipping comments
   {
    myInput.ignore(INT_MAX, '\n'); // skip to next line
    inChar = myInput.peek();       // peak first char of line
    printf("# ignoring a line with comments\n");
   } 
//
 double xValue, yValue;
 while ( !myInput.eof() )          // reading until end of file
   {
    static int nData = 0;          // counter
    nData++;
    myInput >> xValue >> yValue;   // (*)
    if (myInput.fail()&&(!myInput.eof()) )     // check if (*) was successfull
      {
       printf("\n# reading from --%s-- failed due to corrupted data\n",fileName.c_str());
       break;
      }
    cout << " " << nData;
   }
 cout << endl;
 myInput.close();
//
 return 1;
}

IO manipulators

Copy Copy to clipboad
Downlaod Download
#include <iostream>     // standard IO
#include <fstream>      // file streams
#include <sstream>      // string streams
#include <stdio.h>      // printf
#include <iomanip>      // IO manipulations
 
using namespace std;
 
int main()
{
//
// --- using the extraction operator
//
 char ch = 'a';
 cout << endl;
 cout << "please enter something" << endl;
 cout << "stop with zero " << endl;
 while ( (cin >> ch)&&(ch!='0'))
   cout << ch << endl;
 cout << endl;
//
// --- using setw()
//
 char buf[3];
 cout << "now, please enter something long" << endl;
 while ( (cin >> setw(3) >> buf)&&(buf[0]!='0'))
   {                     // note: C style strings require a null terminator 
   string strBuf(buf);   // using string constructor for char* to string conversion
   cout << strBuf << endl;
   }
 cout << endl;
//
 return 1;
}

file position pointers

Copy Copy to clipboad
Downlaod Download
#include <iostream>   // standard IO
#include <fstream>    // file streams
using namespace std;
 
int main()
{
 char str[10];
 ofstream a_file("test.dat");
//
// === create 8 x 8 playing field
//
 for (int i=0;i<8;i++)
   {
   a_file << (char)(97+i) << 0;
   for (int j=1;j<8;j++)
     a_file << " " << (char)(97+i) << j;
   a_file << endl;
   cout << a_file.tellp() << " ";
   }
 cout << endl;
//
// === change entries of field
//
 for (int i=0;i<7;i++)
   {
   long writeHere = 24*i + 3*(i+1);     // line is 24 char long
   a_file.seekp(writeHere, ios::beg);   // advance put postion from file start
   a_file << "@@";
   }
//
// === close file
//
 a_file.close();
 return 1;
}

overwriting stream operators

Copy Copy to clipboad
Downlaod Download
#include <iostream>       // standard IO
#include <stdio.h>        // printf()
#include <assert.h>       // assert()
using namespace std;
 
template <size_t size>
class A_Buffer
{
private:
int pos;                               // for insertion, retriving at (pos-1)
int data[size];
 
public:
bool isEmpty,isFull,outError,inError; 
 
A_Buffer<size>()                       // standard constructor
  { pos=0;           
    assert(size>0);                    // buffer should exsist
    isEmpty  = true;
    isFull   = false;
    inError  = false;                  // when trying to add to full buffer
    outError = false;                  // when trying ro retivve from empty buffer
                                       // alternatively, throw exception
    for (int i=0;i<size;i++)           // not really needed
      data[i] = 0;
  }
 
A_Buffer<size>& operator>>(int &outInt)          // like cin >> variable
  {
  if (pos>0)
    {
    pos--;
    outError = false;
    outInt = data[pos];
    if (pos==0)
      isEmpty = true;
    } else
    {
    outError = true;
    outInt = -1111;
    }
  isFull = false;
  return *this;
  }
 
A_Buffer<size>& operator<<(int newInt)          // like cout << variable
  {
  if (!isFull)
    {
    data[pos] = newInt;
    isEmpty = false;
    inError = false;
    pos++;
    } else
    inError = true;
//
  if (pos==size)
    isFull = true;
  return *this;
  }
 
};
 
int main()
{
 A_Buffer<2> testBuff;   // a buffer for up-to 10 integers
 int testInt = 0;
//
// testBuff >> testInt;   // nothing is in the buffer
 cout << " isEmpty/Full : " << testBuff.isEmpty << " " << testBuff.isFull << endl;
 cout << " in/outError  : " << testBuff.inError << " " << testBuff.outError << endl;
 printf("content of buffer: ");
 while (!testBuff.isEmpty)
   {
   testBuff >> testInt;
   printf("%4d",testInt);
   }
 printf("\n");
//
 testBuff << 5;
 testBuff << 7 << 9;
 cout << " isEmpty/Full : " << testBuff.isEmpty << " " << testBuff.isFull << endl;
 cout << " in/outError  : " << testBuff.inError << " " << testBuff.outError << endl;
 printf("content of buffer: ");
 while (!testBuff.isEmpty)
   {
   testBuff >> testInt;
   printf("%4d",testInt);
   }
 printf("\n");
//
 return 1;
}