A simple solution that prints the first n values in the fibonacci series up to the limit of an unsigned long. The program takes either command line arguments or interactive input for n and has code in place to make the program more flexible, like printing to a file.

76 Views
``````#include <cstdlib>
#include <iostream>
#include <limits>
#include <sstream>
#include <stdexcept>

using namespace std;

/// <summary> Make sure that two values can be summed without overflow. </summary>
template <class T>
bool CanSum( T a, T b ) {
// If the difference of the largest value of T and a
// is less than b, the addition will overflow.
return numeric_limits<T>::max() - a >= b;
}

/// <summary> Find the next Fibonacci value, and update a and b. </summary>
template <class T>
T NextInSequence( T& a, T& b ) {
T next = a + b;

b = a;
a = next;

return next;
}

/// <summary> Print the first n values of the Fibonacci series. </summary>
template <class CharT>
void FibonacciSequence( basic_ostream<CharT>& stream, int n ) {
unsigned long a = 0;
unsigned long b = 1;

for ( int i = 0; i < n && CanSum( a, b ); ++i ) {
cout<< NextInSequence( a, b ) <<"\n";
}
}

/// <summary> Get the next value of type T from the stream. </summary>
/// <parameter name="isConsole"> True if the stream is a console. </parameter>
/// <returns> The input item or T's default value on eof. </returns>
template <class T, class CharT>
T GetNextItem( basic_istream<CharT>& stream, bool isConsole ) {
T item = T();

while ( !( cin >> item ) && !cin.eof() ) {
if ( !isConsole ) {
// Input is automated. All we can do is error.
throw runtime_error( "Invalid item type." );
} else {
// Input is interactive. Get the user to recover.
stream.clear();
stream.sync();
cerr<<"Invalid item type. Try again> ";
}
}

return item;
}

const int INVALID_INDEX = -1;

int main( int argc, char *argv[] ) {
// The index of the Fibonacci number to stop at.
int n = INVALID_INDEX;

if ( argc >= 2 ) {
// Try to get the command line index first.
stringstream( argv ) >> n;
}

if ( n == INVALID_INDEX ) {
// If there's no command line index or the command line
// didn't have a valid index, get it interactively.
cout<<"Fibonacci numbers to generate> ";
n = GetNextItem<int>( cin, true );
}

if ( cin.good() ) {
// Only run the sequence if there were no errors or eof.
FibonacciSequence( cout, n );
}

return 0;
}``````