Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

VictorCacciari

[Resolvido] [Código] sprintf com std::strings

Recommended Posts

Boas Pessoal!

Tinha esse trecho de código em um projeto.

E outro dia, para um projeto menor, me fez falta formatar strings, em C++, como faz-se em C.

Fui buscar esse código e decidi postar por aqui, pode ser que faça falta para alguém tbm.

 

Header:

#ifndef ASTRUTILS_H
#define ASTRUTILS_H

#include <cstdarg>
#include <sstream>
#include <string>
using std::string;

#include <AErr.h> //A definição da classe Err está aqui!

/* InvalidStrFmtErr is thrown by StrPrintF, if the function find a formatting error.
*/
class InvalidStrFmtErr : public Err
{
	public:
		InvalidStrFmtErr(const string &msg) : Err(msg) {}
};

/** @brief returns true if the conversion was sucessfull.
  */
template<typename T>
bool fromStr(T &t, const string &res, std::ios_base& (*radix)(std::ios_base&) = std::dec)
{
std::stringstream strm(res);

	return !((strm >> radix >> t).fail());
}

/** @brief returns true if the conversion was sucessfull.
  */
template<typename T>
bool toStr(const T &t, string &res, std::ios_base& (*radix)(std::ios_base&) = std::dec)
{
std::stringstream strm;

	strm << radix << t;
	res = strm.str();
	return !strm.fail();
}

/** @brief The same operations without error checking.
  */
namespace Unsafe
{
    template<typename T>
    string toStr(const T &t, std::ios_base& (*radix)(std::ios_base&) = std::dec)
    {
    std::stringstream strm;

        strm << radix << t;
        return strm.str();
    }

    template<typename T>
    T fromStr(const string &str, std::ios_base& (*radix)(std::ios_base&) = std::dec)
    {
    std::stringstream strm(str);
    T t;

        strm >> radix >> t;
        return t;
    }
}; //namespace

/** @brief Very similar to sprintf, but work with std strings.
  */
string StrPrintF(string format, ...);
#endif

A classe Err é muito semelhante à classe exception, é a classe base para todas as exceções usadas no meu projeto.

class Err
{
	public:
		Err();
		Err(const string &msg) : message(msg) {}

		string What() const;
	private:
		string message;
};

 

Code:

string StrPrintF(string format, ...)
{
va_list argL;
int i = -1;

	va_start(argL, format);
	
	while ((i = format.find('%', i+1)) != string::npos)
	{
	string ax;
	int subs = 2;
	
		switch(format[i+1])
		{
			case 'd':
			case 'i': toStr<int>(va_arg(argL, int), ax); break;
			case 'x': toStr<int>(va_arg(argL, int), ax, std::hex); break;
			case 'o': toStr<int>(va_arg(argL, int), ax, std::oct); break;
			case 's': ax.assign(va_arg(argL, const char*)); break;
			case 'c': ax = " "; ax[0] = va_arg(argL, int); break;	
			case 'f': toStr<double>(va_arg(argL, double), ax); break;				
			case 'l':
				subs = 3;
				switch(format[i+2])
				{
					case 'd':
					case 'i': toStr<long int>(va_arg(argL, long int), ax); break;
					case 'x': toStr<long int>(va_arg(argL, long int), ax, std::hex); break;
					case 'o': toStr<long int>(va_arg(argL, long int), ax, std::oct); break;
					case 'f': toStr<long double>(va_arg(argL, long double), ax); break;
					default: 
						va_end(argL);
						throw InvalidStrFmtErr(StrPrintF("%c is not a valid format flag after 'l'", format[i+2]));
				}
				break;
				
			case '#':
			{
			int num = va_arg(argL, int);
				subs = 3;
				switch(format[i+2])
				{
					case 'x': toStr<int>(num, ax, std::hex); ax.insert(0, "0x"); break;
					case 'o': toStr<int>(num, ax, std::oct); ax.insert(0, "00"); break;
					default:
						va_end(argL);
						throw InvalidStrFmtErr(StrPrintF("%c is not a valid format flag after '#'", format[i+2]));
				}
				break;
			}
			
			default:
				va_end(argL);
				throw InvalidStrFmtErr(StrPrintF("%c is not a valid format flag", format[i+1]));
		}
			
		format.replace(i, subs, ax);
	}

	va_end(argL);
	return format;
}

Exemplo:

std::cout << StrPrintF("%d = %#x\n", 34, 34);
std::cout << StrPrintF("String testing: '%s'", "abcde"); //Atenção, a flag %s recebe um char*

34 = 0x22

String testing 'abcde'

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.