La cosa può essere gestita utilizzando un albero binario di ricerca :

codice:
#include <stdio.h>
#include <tchar.h>
#include <malloc.h>

typedef struct tagTree
{
	_TCHAR info;
	int count;
	struct tagTree *left;
	struct tagTree *right;
} Tree;

Tree *NewNode(_TCHAR info)
{
	Tree *r;

	r = (Tree *) malloc(sizeof(Tree));

	if(!r)
	{
		_tprintf(_T("Memoria insufficiente\n"));
		return NULL;
	}

	r->info = info;
	r->count = 1;
	r->left = NULL;
	r->right = NULL;

	return r;
}

void TraverseInOrder(Tree *root)
{
	if(!root)
		return;

	TraverseInOrder(root->left);
	if(root->info)
		_tprintf(_T("%c -> %d\n"), root->info, root->count);
	TraverseInOrder(root->right);
}

Tree *UpdateTree(Tree *root, _TCHAR key)
{
	if( !root ) /* L'albero è vuoto */
	{
		root = NewNode(key);
		return root;
	}
	
	while( 1 )
	{
		if ( key < root->info )
		{
			if ( !root->left )
			{
				root->left = NewNode(key);
				break;
			}
			root = root->left;
		}
		else if ( key > root->info )
		{
			if ( !root->right )
			{
				root->right = NewNode(key);
				break;
			}
			root = root->right;
		}
		else
		{
			root->count++;
			break;
		}
	}

	return root;
}

void FreeTree(Tree *root)
{
	if(!root)
		return;

	FreeTree(root->left);
	FreeTree(root->right);
	if( root->info )
		free(root);
}

int _tmain(int argc, _TCHAR* argv[])
{
	_TCHAR * pStr;
	Tree * Radice = NULL;

	if ( argc < 2 )
	{
		_tprintf(_T("Numero di argomenti non valido!\n"));
		return -1;
	}

	pStr = argv[1];

	_tprintf(_T("Stringa di input: %s\n"), pStr);

	while ( *pStr != _T('\0') )
	{
		if ( !Radice )
			Radice = UpdateTree(Radice, *pStr);
		else
			UpdateTree(Radice, *pStr);
		pStr++;
	}

	TraverseInOrder(Radice);

	FreeTree(Radice);

	return 0;
}
Il programma sopra riportato, legge una stringa dalla riga dei comandi e crea l'albero binario ordinato. Per ogni carattere letto dalla stringa di input, se è gia presente nell'albero, incrementiamo il conteggio altrimenti lo inseriamo.
Infine, stampiamo i risultati attraversando l'albero "in order"; visitiamo prima il sottoalbero sinistro, poi la radice e infine il sottoalbero destro.

Avviando il programma con la seguente riga di comando :

ContaCaratteri pippo

l'output è il seguente:

i -> 1
o -> 1
p -> 3