Home   Notes   Contact Me

C++

Local

External


String Manipulation via stringstream

std::stringstream ss; ss << "fred " << 5; std::string strout = ss.str();

Replace sscanf with istringstream

#include <sstream> #include <string> istringstream iss(strToScan); int i; string s; iss >> i; iss >> s;

defining a token into a string

#define DATA greyscale #define MAKESTRINGINNER(x) #x #define MAKESTR(x) MAKESTRINGINNER(x) #define NAME "C:\\jtemp\\" MAKESTR(DATA) ".png" char *str = NAME; // the value of str is "C:\\jtemp\\greyscale.png"

Creating Manipulators

Example Extending ostream

#include <iostream>

ostream& test(ostream& os) {
  os << "*test*";
}

int main() {
  cout << "this is a test: " << test << endl;

  return 0;
}

Example

Note The parameterized manipulator has not been tested.

#include <stdio.h>

class Adapter
{
public:
	virtual Stream& DoIt( Stream &s) = 0;
};

class Stream
{
public:
	Stream& operator << ( char const* zStr) {
		printf( "%s", zStr);
	}
	
	Stream& operator << ( Stream& (*pManipulator)( Stream&) ) {
		return pManipulator( this);
	}
	Stream& operator << ( Adapter & adapt) {
		return adapt.DoIt();
	}
};

Stream& blah( Stream &s)
{
	s << "--Blah!--";
	return s;
}

class Filler : public Adapter
{
private:
	char*	m_zStr;
	int		m_count;
	
public:
	Filler( char* zStr, int count) : m_zStr(zStr), m_count(count) { }
	
	virtual Stream& DoIt( Stream &s) {
		int i;
		for( i = 0; i < m_count; i++) {
			s << m_zStr;
		}
		return s;
	}
};

int main()
{
	Stream str;
	str << "Text" << blah << " hmm " << filler( "birds", 5) << "\n";
	
	return 0;
}

Enums, type safe

template<typename T, int N>
struct enumerator {
  const static int value = N;
  typedef enumerator<T, N + 1> next;
};

struct weekday
{
  // self typedef
  typedef weekday self;

  // 'ctors
  template<int N>
  weekday(const enumerator<self, N>& x) : value(N) { }
  weekday(const self& x) : value(x.value) { }

  // enumerations
  typedef enumerator<self, 0> mon;
  typedef mon::next tue;
  typedef tue::next wed;
  typedef wed::next thu;
  typedef thu::next fri;
  typedef fri::next sat;
  typedef sat::next sun;
  typedef sun::next end_day;

  // operators
  self& operator++(int) { ++value; return *this; }
  self& operator--(int) { --value; return *this; }
  self operator++() { self tmp = *this; ++value; return tmp; }
  self operator--() { self tmp = *this; --value; return tmp; }
  friend bool operator==(const weekday& x, const weekday& y) { return x.value == y.value; }
  friend bool operator!=(const weekday& x, const weekday& y) { return x.value != y.value; }
  operator int() const { return value; }

  // static functions
  static mon begin() { return mon(); }
  static end_day end() { return end_day(); }

  // fields
  int value;
};

void weekday_reaction(const weekday& x) {
  switch (x)
  {
    case (weekday::mon::value) :
      std::cout << "doh! monday" << std::endl;
      break;
    case (weekday::tue::value) :
      std::cout << "doh! tuesday" << std::endl;
      break;
    case (weekday::wed::value) :
      std::cout << "doh! hump-day" << std::endl;
      break;
    case (weekday::thu::value) :
      std::cout << "woohoo! day before friday" << std::endl;
      break;
    case (weekday::fri::value) :
      std::cout << "woohoo! friday" << std::endl;
      break;
    case (weekday::sat::value) :
      std::cout << "woohoo! saturday" << std::endl;
      break;
    case (weekday::sun::value) :
      std::cout << "doh! church!" << std::endl;
      break;
    default:
      std::cout << "whatcha talkin' 'bout willis?" << std::endl;
      break;
  }
}


int main()
{
  weekday_reaction(weekday::sat());
  // weekday_reaction(42); does not compile
  weekday_reaction(weekday::end());

  for (weekday wd = weekday::begin(); wd != weekday::end(); wd++) {
    weekday_reaction(wd);
  }

  system("pause");
  return 0;
}

Pure Virtual Method Called

This happens in the following cases:


File Manipulation

See ./c.html#fileManipulation


Streams

Clases (not complete list)

classincludeInfo
std::ostrstreamstrstream
std::ofstreamfstream

Methods (not complete list)

MethodDescription
bool good()Returns true if no error state on stream
flush()

Other info

Good info http://www.artima.com/cppsource/streamstrings.html

#include <iostream>
#include <iomanip>

cout.fill('0');
cout << hex << setw(10) << left << "text" << setw(20) << right << "more" << dec;
cout.fill(' ');

operator<< for custom types


Manipulators

ManipulaterDescription
std::dec
std::hex
std::oct
std::showbase
std::uppercase

Manipulateors are the same as using this method of a stream:
setf();


std::ostringstream for putting strings in a buffer

#include <sstream>
#include <limits>
#include <iostream>

int main()
{
	std::ostringstream stm;
	stm << "text "
	<< "float: " << 9.0f
	<< "bool: " << false;	

	std::string values = stm.str();
}

std::istringstream to extract from a string

#include <sstream>
#include <limits>
#include <iostream>

int main()
{
	std::istringstream stm;
	stm.str("text 2.5");
	float f;
	std::string s1;
	
	stm >> s1 >> f;
}

Fun with Casting

Function Pointer

// define a pointer
void *fp;
((void(*)())     fp) ( );
((void(*)(int))  fp) ( 1 );

Function that Returns a pointer to a Function

// fun fun fun:
// a function that takes no parameters:
//		GetLoaderStatusCallbackFunc()
// which returns a callback function:
//		void (*)( void *pPara, int flag);
void (*GetLoaderStatusCallbackFunc())( void *pPara, int flag);

Typedefing a function prototype

// typedef
typedef void (*pfCallback)( void* pData);
// function that matches the above typedef
void Callback( void* pData);
// function that uses typedef:
void UseCallback( pfCallback pfCB, void *pData);
// match function used in call
UseCallback( Callback, &data);

Calling convention (i.e. PASCAL aka __stdcall)

// Cast and call it
((void( __stdcall *)(void))pfunc)();

Manipulators

Find them in <ios>

DescriptionExample
hexNext number is written in hex
rightNext item is right justifiedcout.width(10);
cout << right << 1 << endl;

Templates

Gotcha's

// This works in VS7.1
boost::shared_ptr< alpha<foo> >	m_spAlpha;
// This fails in VS7.1
boost::shared_ptr< alpha<foo>>	m_spAlpha2;

Template Specialization

template<class T>
class foo
{
private:
	double m_val;
	
public:
	foo( T);
};

template<class T>
foo<T>::foo( T data)
{
	m_val = (double) data;
}

template<>
foo<char*>::foo( T data)
{
	m_val = atof(data);
}

foo<int> f1(5);
foo<char*> f2("37");

Explicitly Declaring which Signature to use

val = Function< double, int>( 5, 6);

typename

// Sometimes the compiler needs to be told an identifier is a type

template<class DataType>
class SkipList
{
	class const_iterator {
	public:
		const_iterator();
		const_iterator operator++( int);
	};
};

template<class DataType>
inline typename SkipList<DataType>::const_iterator SkipList<DataType>::const_iterator::operator++( int)
{
	m_pAt = m_pAt->GetNode(0);
	return (*this);
}

Character types (default, MBCS, Wide)

ANSI (SBCS)1 byte per char (SBCS is "Single Byte Character Set")
Wide2 bytes per char (typically, but can be any single value)
MBCS# of bytes per char varies ("Multi Byte Character Set")

Wide

#include <wchar.h>
wchar_t A[] = L"xyz";
wchar_t B[4];
wcscpy( B, A);

MBCS

#include <stdlib.h>
char* NextChar( char* p) {
	p += mblen( p, MB_CUR_MAX);
	return p;
}

// All MBCS funcs: (take this as a hint to use WIDE chars instead)
mblen();
mbtowc();
mbstowcs();
wctomb();
wcstombs();

Hexadecimal Escape of character values

// Note the "def" substring must be concatinated so it won't be considered
// part of the hexadecimal escape sequence
char sMulti[] = "abc\x88\xa0" "def";	// abc唖def
char sMulti2[] = "abc\x88\xa0xyz";	// abc唖xyz
wchar_t sWide[] = L"abc\x5516" L"def";	// abc唖def
wchar_t sWide[] = L"abc\x5516xyz";	// abc唖xyz