inputoutput.cc

Introduction

This tutorial and its program shows the usage of input and output files and command line parameters. With the use of input files its no longer necessary to recompile the whole program when you want to change a parameter and its no longer necessary to write a huge number of parameters on the command line.

With a carefully designed order of parsing the command line options and reading the input file, it is even possible that the parameters on the command line overwrite the parameters in the input file.

Caution The lowercase/capital letter i / I/strong> is reserved by the parser as complex number and is not allowed to be used while defining variables inside a *.cig file.

The input file has a C-like syntax. You can derive the structure from the following example:

string title "testing blending maps"
string author "Philipp Frauenfelder, 2001"
int level 1
int polynomial 15
// Viertelkreis
// string uex "(y*(1-x)*(x-y))"
// string fex "(-(-2+2*x-2*y+(-1+x)*(x-y)*y))"
// Dreieck (0,-1), (1,0), (0,1)
string uex "(x*(1-x-y)*(x-1-y))"
string fex "(-4 + 4*x + x*(1 - x - y)*(-1 + x - y))"
array string bcform {
1 "(0)"
2 "(1)"
}
// 0 means FREE, 1 means DIRICHLET, 2 means NEUMANN
array int bctype {
1 1
2 2
}
string meshouteps "blendmesh.eps"
string meshoutdx "blendmesh.dx"
string dataoutnumeric "blendnumeric.data"
string parameterout "blendoutput2.concepts"
double a 1.0 /* just a parameter */
bool subdivide false
The results from the program are stored in a similar structure. At
the end of a program, it is possible to write the input and output
data into one file. The output file has the same syntax and
structure as the input file and can therefore be used as an input
file to reproduce the results at a later time. See the <a
href="#Results">results section</a> for an example.

@dontinclude inputoutput.cc
@section commented Commented Program

The first few lines in a code for concepts are filled with the
include files. I put the system includes first here.
@until unistd.h
Then, there are the Concepts includes: 
<ul>
<li>basics.hh for the exception handling code and other things.
<li>toolbox.hh for the toolbox, including the intput file parser
and the handling of input and output data.
</ul>
Since there are no real computations in the code, no more include files
from Concepts are needed.
@until toolbox.hh
@skip main
All code in this example is in one large routine, the main program.
@until main
@skip uint
Some default values for the parameters used. \c l and \c p are just two
variables. If \c debug is set to true, more information is printed to
screen.
@until debug
A big try block to catch exceptions. More and more runtime errors
in Concepts are reported by throwing an exception.
@skip try
@until try
First, set up the input parameter class: some parameters
are set up with a default value.
@skip concepts::InputParser
@until parameterout
The variable outputParameter is for easier access to the output
area. There, the results of the computations can be stored and
eventually written to disk if necessary.
@skip input
@until input
Prepare an array for values computed later. This array is then
added to \c table which is able to nicely format the content of
the different arrays (e.g. for later processing with Gnuplot).
@skip error
@until inputfile

@subsection parsing Command Line Parsing
Here, we start with the command line parsing. See the man page
for \c getopt for more information.

In the second line of the following code fragement, the string
defines what command line arguments are allowed and if they take a
parameter (:) or not. The \c switch statement has an entry
for every command line argument listed in the string. There, the
parameter is available as \c optarg. The \c default
target of the \c switch clause prints some
usage information (ie. help for the command line arguments).

The parameters are processed in the order they appear on the
command line. When first specifying an input file with \c -f, the
values in the file can be overridden with additional command line
arguments after \c -f.
@until }
Print the parameters to show the user what is going on.
@skip std::cout
@until --
@until --
Next, the parameters from the command line or the input file are
stored in the respective variables. This is only used for
abbrevation.
@skip l
@until polynomial

@subsection comp Computations
Here are some dummy computations to fill the output area with
content.
@skip outputParameters.addInt
@until error

@section output Output
Finally, the input and output data are written to disk with some more
information about the user and the system in the header of the
file.
@skip std::cout
@until delete
This prints the table and its content to the screen and also
stores it with high precision in a file suitable for later
processing with Gnuplot.
@skip table
@until }
Here, all exceptions derived from the base exception class
(concepts::ExceptionBase) in Concepts are catched and printed. You
can test this out by not giving the name of the input file on the
command line. Then the parameter \c parameterout does not exist
and the library will throw and exception which is caught here.
@until }
@until }

@section Results
The output of the program called without parameters: @code

[inputoutput]

Parameters: input file = string author "(empty)" string comment "(empty)" string parameterout "inputoutput.out" string title "(empty)" int level 0 int polynomial 1

bool debug false

– Writing gathered data to disk: inputoutput.out ResultsTable( error error 0 1 1 0.5 2 0.25 3 0.125 4 0.0625 5 0.03125 6 0.015625 7 0.0078125 8 0.00390625 9 0.00195312 )

The program creates the following output files:
- \c inputoutput.out: @code

/* program: inputoutput

  • command: inputoutput
  • input file: */ string author "(empty)" string comment "(empty)" string parameterout "inputoutput.out" string title "(empty)" int level 0 int polynomial 1 bool debug false end // output starts here int nelm 10 array double error { 0 1 1 0.5 2 0.25 3 0.125 4 0.0625 5 0.03125 6 0.015625 7 0.0078125 8 0.00390625 9 0.00195312 }
    • inputoutput.gnuplot:@code # error error 0 1 1 0.5 2 0.25 3 0.125 4 0.0625 5 0.03125 6 0.015625 7 0.0078125 8 0.00390625 9 0.001953125
      Note the \c end keyword at the end of the input
      part and right before the output part. When reading in this file as
      input file, the parsing stops right there, ie. the previous output
      data is not read in.
      
      @section complete Complete Source Code
      @author Philipp Frauenfelder, 2004
      

#include <cmath>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <unistd.h>
#include "basics.hh"
#include "toolbox.hh"
int main(int argc, char** argv) {
uint l = 0;
uint p = 1;
bool debug = false;
try {
// ********************************************************** input data **
concepts::InputParser input(true);
concepts::InOutParameters& inputParameters = input.inputParameters();
inputParameters.addInt("level", l);
inputParameters.addInt("polynomial", p);
inputParameters.addBool("debug", debug);
inputParameters.addString("parameterout", "inputoutput.out");
concepts::InOutParameters& outputParameters = input.outputParameters();
outputParameters.addArrayDouble("error");
table.addMap(concepts::ResultsTable::DOUBLE, "error", outputParameters);
std::string inputfile;
int opt;
while ((opt = getopt(argc, argv, "-f:l:p:d")) != EOF)
switch(opt) {
case 'l': inputParameters.addInt("level", std::atoi(optarg)); break;
case 'p': inputParameters.addInt("polynomial", std::atoi(optarg));
break;
case 'f': inputfile = std::string(optarg);
input.parse(inputfile);
break;
case 'd': inputParameters.addBool("debug", true); break;
default:
std::cout << "Usage: " << argv[0]
<< " [-l LEVEL] [-p DEGREE] [-f FILE] [-d]"
<< std::endl
<< "where" << std::endl
<< " FILE: name of the input file" << std::endl
<< " LEVEL: level of refinement" << std::endl
<< " DEGREE: polynomial degree" << std::endl
<< " -d: print the matrices" << std::endl
<< "Options given after the input file override the values "
<< "read from the"
<< std::endl << "input file." << std::endl;
std::exit(1);
break;
}
// ***************************************************** show parameters **
std::cout << '[' << argv[0] << "]" << std::endl;
std::cout << "--" << std::endl;
std::cout << "Parameters:" << std::endl
<< " input file = " << inputfile << std::endl << inputParameters;
std::cout << "--" << std::endl;
l = inputParameters.getInt("level");
p = inputParameters.getInt("polynomial");
// ******************************************************** computations **
outputParameters.addInt("nelm", 10);
for (int i = 0; i < 10; ++i)
outputParameters.addArrayDouble("error", i, 1.0/(1<<i));
// ************************************** output of input data and other **
std::cout << "--" << std::endl
<< "Writing gathered data to disk: "
<< inputParameters.getString("parameterout") << std::endl;
std::ofstream *ofs = new std::ofstream
(inputParameters.getString("parameterout").c_str());
*ofs << "/* program:\t" << argv[0] << std::endl
<< " * command:\t";
for (int i = 0; i < argc; ++i)
*ofs << argv[i] << " ";
*ofs << std::endl
<< " * input file:\t" << inputfile << std::endl;
*ofs << " */" << std::endl << input;
delete ofs;
std::cout << table << std::endl;
ofs = new std::ofstream("inputoutput.gnuplot");
*ofs << std::setprecision(20);
delete ofs;
}
std::cout << e << std::endl;
return 1;
}
return 0;
}

Base class for exceptions.
Definition: exceptions.hh:86
Holds parameters in hashes.
Definition: inputOutput.hh:75
void addArrayDouble(const char *array, const bool newArray=false)
Creates an empty array for doubles if necessary.
int getInt(const char *name, const int value=INT_MAX) const
Returns an int from the hash of ints.
void addString(const char *name, const char *value)
Adds a string to the hash of strings.
void addBool(const char *name, const int value)
Adds a bool to the hash of bools.
Parses an input file and extracts parameters.
Definition: inputOutput.hh:443
void addMap(enum mapTypes type, const char *name, const InOutParameters &holder)
InOutParameters & inputParameters()
Returns the input data.
Definition: inputOutput.hh:461
void addInt(const char *name, const int value)
Adds an int to the hash of ints.
InOutParameters & outputParameters()
Returns the output data.
Definition: inputOutput.hh:464
void parse()
Parses the input file.
Organizes the results in the hashes from InOutParameters in a nice table.
Definition: resultsTable.hh:23
void print(std::ostream &os) const
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich