• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

gocho

[C++] Dúvida: C/o criar 1 variavel para qq tipo de dado? (Resolvido)

9 mensagens neste tópico

Boas! é o seguinte, é possível em c++ criar uma variável que contenha um qualquer tipo de dado e posteriormente identificar qual o tipo da variável? Se algum me puder ajudar, agradeço. Cumprimentos

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

EM concreto, o que eu quero, se for possivel, é criar um mecanismo, em que uma variavel possa ser uma string ou um inteiro, e posteriormente avaliar qual o tipo de variavel....

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

bem-vindo ao fórum :P

não uso muito o C++, mas penso que isso é possível.

podes fazer as coisas à C, definindo uma 'union' ou mesmo usando apontadores.

o mais "correcto" (tendo em conta que o C++ é uma linguagem OO) será criares uma classe que terá duas subclasses, uma que te permite guardar um inteiro e outra que te permite guardar uma string.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pelo que percebi da tua dúvida, sim é possível.

Para isso terás de utilizar, os templates nas classes.

Tens aqui um exemplo:

 
#ifndef GRAFO_H_
#define GRAFO_H_

template <class N, class A> 
class Grafo;

template <class N, class A> 
std::ostream & operator<<(std::ostream &out, const Grafo<N, A> &g) {
g.imprimir(out);
return out;
}

template <class N, class A> 
class Grafo { 
    struct Aresta { A val; bool usada; }; 
    struct No { N val; Aresta *arestas; }; 
    No *v_nos;   // vector de nós 
    int tamanho; 
    int nn;     // nº de nós 
    int na;     // nº de arestas 
    
    int procurarIndice(const N &index) const;

  public: 
    Grafo<N,A> (const int n = 10); 
    ~Grafo(); 
    Grafo & inserir_no(const N &dados); 
    Grafo & inserir_aresta(const N &inicio, const N &fim, const A &dados); 
    Grafo & eliminar_aresta(const N &inicio, const N &fim); 
    A & valor_aresta(const N &inicio, const N &fim); 
    int n_arestas(void) const; 
    int n_nos(void) const; 
    int capacidade (void) const; 
    void imprimir(std::ostream &os) const; 
friend ostream & operator<<(ostream & out, const Grafo<N, A> &g);
}; 


template <class N, class A>
int Grafo<N,A>::procurarIndice(const N &inicio) const {
int i = 0;
bool enc = false;

while ((i < nn) && (enc == false)) {
	if (v_nos[i].val == inicio)
		enc = true;
	else
		i++;
}

if (enc == false) {

}

return i;
}

/* --- CONSTRUTOR ---*/
template <class N, class A> 
std::ostream & operator<<(std::ostream &out, const Grafo<N, A> &g);

template <class N, class A>
Grafo<N,A>::Grafo(const int n): tamanho(n), nn(0), na(0) {
v_nos = new No[tamanho];
}
template <class N, class A>
Grafo<N,A>::~Grafo() {
delete v_nos;
}
/* --- FIM -----------*/


/* ********* INSERIR *********** */
template <class N, class A>
Grafo<N,A>& Grafo<N,A>::inserir_no(const N &dados) {
if (nn == tamanho) {
	//ERRO CHEIO
}

int i = 0;
bool enc = false;
while ((i < nn) && (enc == false)) {
	if (v_nos[i].val == dados.val)
		enc = true;
	else
		i++;
}

if (enc == true) {
	//ERRO IGUAL
}

v_nos[nn].val = dados;
v_nos[nn].arestas = new Aresta[tamanho];
nn++;

return *this;
}

template <class N, class A>
Grafo<N,A>& Grafo<N,A>::inserir_aresta(const N &inicio, const N &fim, const A &dados) {

int indexInicio = procurarIndice(inicio);
int indexFim = procurarIndice(fim);

if (v_nos[indexInicio].arestas[indexFim].usada == true) {
	//ERRO ARESTA EM USO
}

v_nos[indexInicio].arestas[indexFim].val = dados;
v_nos[indexInicio].arestas[indexFim].usada = true;

return *this;

}

template <class N, class A>
Grafo<N,A>& Grafo<N,A>::eliminar_aresta(const N &inicio, const N &fim) {
int indexInicio = procurarIndice(inicio);
int indexFim = procurarIndice(fim);

v_nos[indexInicio].arestas[indexFim].usada = false;
}

/* ********* FIM *********** */

/* --- METODOS GET ----*/

template <class N, class A>
A& Grafo<N,A>::valor_aresta(const N &inicio, const N &fim) {

int indexInicio = procurarIndice(inicio);
int indexFim = procurarIndice(fim);

if (v_nos[indexInicio].arestas[indexFim].usada == false) {
	//ERRO ARESTA NAO existe
}

return v_nos[indexInicio].arestas[indexFim];
}

template <class N, class A>
int Grafo<N,A>::n_arestas(void) const {
return na;	
}
template <class N, class A>
int Grafo<N,A>::n_nos(void) const {
return nn;
}
template <class N, class A>
int Grafo<N,A>::capacidade(void) const {
return tamanho;
}
/* ------ FIM   ----*/


template <class N, class A>
void Grafo<N,A>::imprimir(std::ostream &os) const {
int i = 0, j = 0;
while (i < nn) {
	j = 0;

	os << "( ";
	os << v_nos[i].val << " ";
	while (j < tamanho) {
		if (v_nos[i].arestas[j].usada == true)
			os << "[" << v_nos[j].val << " " << v_nos[i].arestas[j].val << "] ";
	}
	os << ") ";
}
}


#endif

Isso era um exercicio da cadeira de algoritmos e estruturas de dados, pode ver aqui o enunciado.

Se depois vires o ficheiro teste grafo que se encontra no fim da página, irás reparar que quando declaras uma variável do tipo grafo tens de lhe dar duas classes às quais vão pertencer os objectos. Neste caso, foi:

Grafo<string, int> grf;

Mas também poderia ter sido outros quaisquer, o pré-requisito dos tipos que queiras lá meter é que tenhas definidos os operadores das operações que possas vir a efectuar na classe grafo. (isto, caso cries uma nova classe e a queiras inserir no grafo)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

lol.. nem vou comentar.. hehe.. já percebi, mas isso é materia para uma cadeira que vou ter no proximo semestre, e ultrapassa em muito o conteudo da cadeira de c++ que estou a ter. Vou abordar o problema de uma maneira diferente, mais simples, apesar de incorrecta. Obrigado pela ajuda :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O meu problema é ler uma variavel em que eu não sei se é uma string ou se é um inteiro. Eu preciso de pesquisar a existencia de uma pessoa pelo seu nome ou pelo seu numero de utente. Mas quero que o utilizador do programa tenha a sua frente um interface do tipo:

"Introduza o nome ou o numero do utente que pretende procurar!"

Ai o utilizador introduz o dado que lhe convem, que pode ser uma sting ou um inteiro.

A minha solução é a seguinte:

char nome[50];

int aux;

if (strlen(nome) < 10){

    aux = atoi(nome);

    pesquisar(aux);

}

pesquisar(nome);

Deu para perceber? Sei que esta abordagem não é a ideal, limita o numero maximo de utentes e caso o utilizador introduza um nome com 9 caracteres, o programa vai converter para inteiro.

Os meus conhecimentos disto não me permitem ir mais longe, tenciono explicar os problemas desta abordagem no relatorio. Isto vai ser implementado apenas para poder demonstrar certas caracteristicas da linguagem.

Cumps

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes sempre contornar isso apresentando dois métodos de procura ao utilizador: um que procura pelo número e outro pelo nome, e o utilizador quando for a procurar escolhe um.

1- Procura pelo nome
2- Procura pelo numero

Escolha: x

if(x== 1){
cout << "Introduza o nome: ";
cin >> var;
//procura pelo nome
}
else if(x==2){
cout << "Introduza o numero: ";
cin >> var;
//procura pelo numero
}

Também tens sempre a opção de fazer de outra forma, que é:

Introduza o que pretende procurar ( [no xxxxx] - nome, [nu xxxxx] - numero ): 

Esta segunda opção, não a acho tão user friendly como a primeira e envolve um bocado mais de trabalho, pois precisas de um parser para processar o "no" ou "nu" e depois o resto da string.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E porque não aproveitar da função atoi?

Sepostamente no nome não deveria aperecer números, logo quando o atoi recebe uma string que não é um número devolve 0!

Convert string to integer.

  Parses string interpreting its content as a number and returns an int value.

Parameters.

string

String representing an integer number. The number is considered until a non-numeric character is found (digits, and signs are considered valid numeric characters for this parameter as specified in format). The format used is:

[whitespaces][+|-][nnnnn]

(where whitespaces are any tab or space character and nnnnn may be any number of digits)

Return Value.

  The converted integer value of the input string.

  On overflow the result is undefined.

  If an error occurs 0 is returned.

Cumpr. bk@ero  ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora