C vs. C++

A comparison of the C and C++ versions of a simple line-reversal program:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>


static void readlines( FILE* f );
static void* malloc_check( size_t size );
static void* realloc_check( void* ptr, size_t size );
static char* strdup_check( char* str ); 
static void check( void* ptr );


static char* argv0;
static int nlines, maxlines;
static char** lines;


int
main( int argc, char** argv )
    {
    FILE* f;
    int i;

    argv0 = argv[0];
    maxlines = 100;
    lines = (char**) malloc_check( maxlines * sizeof(char*) );
    nlines = 0;

    if ( argc == 1 )
	readlines( stdin );
    else
	for ( i = 1; i < argc; ++i )
	    {
	    if ( strcmp( argv[i], "-" ) == 0 )
		readlines( stdin );
	    else
		{
		f = fopen( argv[i], "r" );
		if ( f == (FILE*) 0 )
		    {
		    perror( argv[i] );
		    exit( 1 );
		    }
		readlines( f );
		fclose( f );
		}
	    }

    for ( i = nlines - 1; i >= 0; --i )
	fputs( lines[i], stdout );

    exit( 0 );
    }


static void
readlines( FILE* f )
    {
    char line[30000];

    while ( fgets( line, sizeof(line), f ) != NULL )
	{
	if ( nlines >= maxlines )
	    {
	    maxlines *= 2;
	    lines = (char**) realloc_check(
		(void*) lines, maxlines * sizeof(char*) );
	    }
	lines[nlines] = strdup_check( line );
	++nlines;
	}
    }


static void*
malloc_check( size_t size )
    {
    void* ptr = malloc( size );
    check( ptr );
    return ptr;
    }


static void*
realloc_check( void* ptr, size_t size )
    {
    ptr = realloc( ptr, size );
    check( ptr );
    return ptr;
    }


static char*
strdup_check( char* str )
    {
    str = strdup( str );
    check( (void*) str );
    return str;
    }


static void
check( void* ptr )
    {
    if ( ptr == (void*) 0 )
	{
	(void) fprintf( stderr, "%s: out of memory\n", argv0 );
	exit( 1 );
	}
    }

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


typedef vector<string> LineVec;
static LineVec lines;


static void readlines( istream& f );


int
main( int argc, char** argv )
    {
    if ( argc == 1 )
	readlines( cin );
    else
	for ( int i = 1; i < argc; ++i )
	    {
	    if ( strcmp( argv[i], "-" ) == 0 )
		readlines( cin );
	    else
		{
		ifstream f( argv[i] );
		if ( f.bad() )
		    {
		    cerr << argv[0] << ": error opening " << argv[i] << "\n";
		    exit( 1 );
		    }
		readlines( f );
		f.close();
		}
	    }

    for ( LineVec::reverse_iterator i = lines.rbegin(); i != lines.rend(); ++i )
	cout << *i << "\n";

    exit( 0 );
    }


static void
readlines( istream& f )
    {
    char line[30000];

    while ( f.getline( line, sizeof(line) ) )
	lines.push_back( line );
    }

And here are the C and C++ versions of a similar paragraph-reversal program:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>


static void readpars( FILE* f );
static void* malloc_check( size_t size );
static void* realloc_check( void* ptr, size_t size );
static char* strdup_check( char* str );
static void check( void* ptr );


static char* argv0;
static int npars, maxpars;
static char*** pars;
static int nlines, maxlines;
static char** lines;


int
main( int argc, char** argv )
    {
    FILE* f;
    int i;
    char** lp;

    argv0 = argv[0];
    maxpars = 100;
    pars = (char***) malloc_check( maxpars * sizeof(char**) );
    npars = 0;

    if ( argc == 1 )
	readpars( stdin );
    else
	for ( i = 1; i < argc; ++i )
	    {
	    if ( strcmp( argv[i], "-" ) == 0 )
		readpars( stdin );
	    else
		{
		f = fopen( argv[i], "r" );
		if ( f == (FILE*) 0 )
		    {
		    perror( argv[i] );
		    exit( 1 );
		    }
		readpars( f );
		fclose( f );
		}
	    }

    for ( i = npars - 1; i >= 0; --i )
	{
	for ( lp = pars[i]; *lp != (char*) 0; ++lp )
	    fputs( *lp, stdout );
	if ( i > 0 )
	    fputs( "\n", stdout );
	}

    exit( 0 );
    }


static void
readpars( FILE* f )
    {
    char line[30000];

    maxlines = 100;
    lines = (char**) malloc_check( maxlines * sizeof(char*) );
    nlines = 0;

    while ( fgets( line, sizeof(line), f ) != NULL )
	{
	/* Is it a blank line? */
	if ( line[0] == '\n' || line[0] == '\r' )
	    {
	    if ( nlines != 0 )	/* ignore multiple blank lines */
		{
		/* Save previous paragraph. */
		if ( npars >= maxpars )
		    {
		    maxpars *= 2;
		    pars = (char***) realloc_check(
			(void*) pars, maxpars * sizeof(char**) );
		    }
		pars[npars] = lines;
		++npars;
		/* Start new paragraph. */
		maxlines = 100;
		lines = (char**) malloc_check( maxlines * sizeof(char*) );
		nlines = 0;
		}
	    }
	else
	    {
	    /* Save this line. */
	    if ( nlines >= maxlines )
		{
		maxlines *= 2;
		lines = (char**) realloc_check(
		    (void*) lines, maxlines * sizeof(char*) );
		}
	    lines[nlines] = strdup_check( line );
	    ++nlines;
	    }
	}

    /* Save last paragraph. */
    if ( nlines != 0 )
	{
	if ( npars >= maxpars )
	    {
	    maxpars *= 2;
	    pars = (char***) realloc_check(
		(void*) pars, maxpars * sizeof(char**) );
	    }
	pars[npars] = lines;
	++npars;
	}
    }


static void*
malloc_check( size_t size )
    {
    void* ptr = malloc( size );
    check( ptr );
    return ptr;
    }


static void*
realloc_check( void* ptr, size_t size )
    {
    ptr = realloc( ptr, size );
    check( ptr );
    return ptr;
    }


static char*
strdup_check( char* str )
    {
    str = strdup( str );
    check( (void*) str );
    return str;
    }


static void
check( void* ptr )
    {
    if ( ptr == (void*) 0 )
	{
	(void) fprintf( stderr, "%s: out of memory\n", argv0 );
	exit( 1 );
	}
    }

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


static void readpars( istream& f );


typedef vector<string> LineVec;
typedef vector<LineVec> ParVec;
static ParVec pars;


int
main( int argc, char** argv )
    {
    if ( argc == 1 )
	readpars( cin );
    else
	for ( int i = 1; i < argc; ++i )
	    {
	    if ( strcmp( argv[i], "-" ) == 0 )
		readpars( cin );
	    else
		{
		ifstream f( argv[i] );
		if ( f.bad() )
		    {
		    cerr << argv[0] << ": error opening " << argv[i] << "\n";
		    exit( 1 );
		    }
		readpars( f );
		f.close();
		}
	    }

    for ( ParVec::reverse_iterator i = pars.rbegin(); i != pars.rend(); ++i )
	{
	if ( i != pars.rbegin() )
	    cout << "\n";
	for ( LineVec::iterator j = i->begin(); j != i->end(); ++j )
	    cout << *j << "\n";
	}

    exit( 0 );
    }


static void
readpars( istream& f )
    {
    char line[30000];
    LineVec lines;

    while ( f.getline( line, sizeof(line) ) )
	{
	/* Is it a blank line? */
	if ( line[0] == '\0' )
	    {
	    if ( lines.size() != 0 )	/* ignore multiple blank lines */
		{
		pars.push_back( lines );
		lines.clear();
		}
	    }
	else
	    lines.push_back( line );
	}

    /* Save last paragraph. */
    if ( lines.size() != 0 )
	pars.push_back( lines );
    }


Back to Jef's Web Page.