Ir ao conteúdo

C Problema em ordenação de registro (por parametro) bubble sort


Ir à solução Resolvido por arfneto,

Posts recomendados

Postado

Sou leigo quando se fala de passagem Referencia, não sei o o que está errado, na função ordenar.

 

 

 

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

typedef struct
{
	int codigo;
	char nome[31];
	int telefone;
	char email[51];
}	Cliente;

typedef struct
{
	int limite;
	int total;


	Cliente	cl[30];
}	Cadastro;

void imprimirLista(Cadastro*);
int  novoCadastro(Cadastro*);
int  ordenar(Cadastro*);
//main, por enquanto somente duas funções
int main()
{
	setlocale(LC_ALL,"portuguese");
	Cadastro	cad;

	novoCadastro(&cad);
	ordenar(&cad);
	imprimirLista(&cad);
	system("pause");
	return 0;
};
//função que imprime tudo na tela 
void imprimirLista(Cadastro* cad)
{
	int i;
	printf("cadastro tem %d de %d clientes\n\n",
		cad->total, cad->limite);
		
	for ( i = 0; i < cad->total; i += 1){ // i = i + 1;
		printf("\t-----> %d\n", cad->cl[i].codigo);
		printf("\t%s\n", cad->cl[i].nome);
		printf("\t%d\n", cad->cl[i].telefone);
		printf("\t%s\n", cad->cl[i].email);	
	}
	return;
}
//função que cadastra clientes 
//por enquanto somente tem memória temporária
int novoCadastro(Cadastro* cad)
{
	Cliente modelo;
	int i, opcao;
	//cadastro por quantidade
	printf("Quantos clientes deseja cadastrar?");
	scanf("%d",& opcao);
	for (i=0; i < opcao; i++)
	{
		printf("\ndigite o código: ");
		scanf("%d",&modelo.codigo);
		fflush(stdin);
		printf("\ndigite o nome: ");
		gets(modelo.nome);
		printf("\nDigite o telefone: ");
		scanf("%d",&modelo.telefone);
		printf("\nDigite o email: ");
		fflush(stdin);
		gets(modelo.email);
		cad->cl[i] = modelo;
	}
	cad->total = i;
	cad->limite = 30;
	return 1;
};
// ordena do menor para o maior para função imprimirLista

/*Estou com problemas na hora de imprimir, parece que tem algo errado...*/
int ordenar (Cadastro* cad)
{
	int i, j;
	Cliente		troca;
	for (i = 0; i < 28; i++)
	{
		for (j = i + 1; j < 29; j++)
		{
			if ((cad->cl[i].codigo) > (cad->cl[j].codigo)) // acredito que o erro esteja nessa linha
			{
				troca = cad->cl[i];
				cad->cl[i] = cad->cl[j];
				cad->cl[j] = troca;
			}
		}
	}
	return 1;
}

 

adicionado 11 minutos depois

tentei modificar para esse jeito e é falho, segue ->

 

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

typedef struct
{
	int codigo;
	char nome[31];
	int telefone;
	char email[51];
}	Cliente;

typedef struct
{
	int limite;
	int total;


	Cliente	cl[30];
}	Cadastro;

void imprimirLista(Cadastro*);
int  novoCadastro(Cadastro*);
int  ordenar(Cadastro*);
//main, por enquanto somente duas funções
int main()
{
	setlocale(LC_ALL,"portuguese");
	Cadastro	cad;
//sequencia
	novoCadastro(&cad);
	ordenar(&cad);
	imprimirLista(&cad);
	system("pause");
	return 0;
};
//função que imprime tudo na tela 
void imprimirLista(Cadastro* cad)
{
	int i;
	printf("cadastro tem %d de %d clientes\n\n",
		cad->total, cad->limite);
		
	for ( i = 0; i < cad->total; i += 1){ // i = i + 1;
		printf("\t-----> %d\n", cad->cl[i].codigo);
		printf("\t%s\n", cad->cl[i].nome);
		printf("\t%d\n", cad->cl[i].telefone);
		printf("\t%s\n", cad->cl[i].email);	
	}
	return;
}
//função que cadastra clientes 
//por enquanto somente tem memória temporária
int novoCadastro(Cadastro* cad)
{
	Cliente modelo;
	int i, opcao;
	//cadastro por quantidade
	printf("Quantos clientes deseja cadastrar?");
	scanf("%d",& opcao);
	for (i=0; i < opcao; i++)
	{
		printf("\ndigite o código: ");
		scanf("%d",&modelo.codigo);
		fflush(stdin);
		printf("\ndigite o nome: ");
		gets(modelo.nome);
		printf("\nDigite o telefone: ");
		scanf("%d",&modelo.telefone);
		printf("\nDigite o email: ");
		fflush(stdin);
		gets(modelo.email);
		cad->cl[i] = modelo;
	}
	cad->total = i;
	cad->limite = 30;
	return 1;
};
// ordena do menor para o maior para função imprimirLista

/*Estou com problemas na hora de imprimir, parece que tem algo errado...*/
int ordenar (Cadastro* cad)
{
	int i, j;
	Cliente		troca, trocai, trocaj;
	for (i = 0; i < 28; i++)
	{
		for (j = i + 1; j < 29; j++)
		{
			trocai = cad->cl[i];
			trocaj = cad->cl[j];
			if ((trocai.codigo) > (trocaj.codigo))
			{
				troca = trocai;
				trocai = trocaj;
				trocaj = troca;
				// atribui de volta 
				cad->cl[i] = trocai;
				cad->cl[j] = trocaj;
			}
		}
	}
	return 1;
};

 

  • Obrigado 1
  • Solução
Postado

Acho que eu te falei um certo número de vezes, e te mostrei códigos completos e exemplos, como em 


E eu imaginei que tinha entendido que é sempre um atraso colocar menus e ler coisas do teclado em programas que ainda não estão prontos. Imagino que tenha referências que julgue melhores que a minha simples sugestão. Professores e livros que digam o contrário 🤔 talvez.

 

Mas eu estou certo e aqui está você com o programa igualzinho de volta

 

Sobre a função ordena()
 

image.png.b04da662990ead56bc36bf92fc94cebb.png

 

Pois é. A cada vez que vai testar você fica aí sentado inventando esses dados?

 

Chegou a digitar os 30 alguma vez? 

int ordenar (Cadastro* cad)
{
	int i, j;
	Cliente		troca;
	for (i = 0; i < 28; i++)
	{
		for (j = i + 1; j < 29; j++)
		{
          
          ...

 

Se o usuário --- você --- estiver meio sem paciência e digitar apenas DOIS valores, que acha que vai rolar com esses loop com valores fixos em 28 e 29?

 

Para que você acha que eram as variáveis cad->limite e cad->total?

 

int novoCadastro(Cadastro* cad)
{
	Cliente modelo1 = {
		.codigo = 12,
		.nome = "cliente 12"
	};
	Cliente modelo2 = { 13,"cliente 13" };
	cad->cl[0] = modelo1;
	cad->cl[1] = modelo2;
	cad->cl[2] = modelo2;
	cad->cl[3] = modelo1;

	cad->total = 4;
	cad->limite = 30;
	return 4;
};

Sobre essa função acima eu te mostrei com detalhes e achei que você tinha entendido, já que nada mais perguntou.

 

E aí pergunto eu: porque razão não testou a função 

int ordenar(Cadastro* cad)

que escreveu com esse cadastro e editando nele direto com outros valores, para testar sua função em minutos ao invés de dias?

 

Se recorda de ter aí um programa completo que roda isso?

 

Não entendeu mesmo que seria só chamar

Cadastro cad;

    novoCadastro(&cad); // ja vem preenchido
    imprimirLista(&cad); // mostra ainda fora de ordem
    ordena(&cad); 
    imprimirLista(&cad); // mostra depois de ordenar

??

 

  • Amei 1
Postado
19 minutos atrás, arfneto disse:

inventando esses dados?

Eu não sabia usar o scanf e gets com registro por referencia, fiz isso praticamente pra aprender a usar e acabei não modificando para aquele seu modo mais prático.

 

19 minutos atrás, arfneto disse:

E eu imaginei que tinha entendido

Eu entendi, mas como citei acima, eu acabei não modificando porque peguei no código agora 23:00, ai esqueci, bem lembrado!

 

19 minutos atrás, arfneto disse:

Para que você acha que eram as variáveis cad->limite e cad->total?

P#ta m%&da , vou reconstruir aqui. Não tenho desculpas. Vou martelar esses erros na minha mente!

 

19 minutos atrás, arfneto disse:

Não entendeu mesmo que seria só chamar

Muito obrigado, muito obrigado mesmo! vou arrumar esse atraso e esse bug autoral  :)

Postado
8 horas atrás, Luiz Paulo Escobar disse:

Eu não sabia usar o scanf e gets com registro por referencia, fiz isso praticamente pra aprender a usar e acabei não modificando para aquele seu modo mais prático

 

Eu realmente não entendo esse lance de registro por referência de que fala. Veja os protótipos:

    int fscanf(FILE *stream_name, const char *set_of_characters)
  
    char *fgets(char *str, int n, FILE *stream)

trata-se da realidade.

fgets() espera um endereço, o lugar para onde vai transferir o que ler, saída. Um int com o limite de quanto vai ler, entrada, e um endereço da estrutura que descreve o arquivo de onde "fget" as coisas, entrada. Então é isso o que você deve fornecer. 

scanf() é igual. Essas rotinas não alocam memória então você tem que passar um endereço de algum lugar para elas transferirem o que conseguirem "scan" ou "get" de algum lugar que você também tem que dizer qual é.

 

Então você sempre usa por referência. SEMPRE.

 

Como eu te disse, scanf() foi escrita para tratar entrada formatada. O teclado não é isso: o cara pode digitar qualquer coisa. E claro que vai dar problema. Você pode tentar contornar com os especificadores, com essa gíria de limpar o buffer, com orações fervorosas, feitiços e tal. Mas sempre vai ter problemas.

 

fgets() e fgetc() para ler linhas e letras é mais seguro para ler do teclado. Mesmo assim problemático porque o cara tem 105 teclas para experimentar.

 

Seguro mesmo só lendo as teclas sem mostrar e só aceitar as que fazem sentido na hora. E não mostrar a letra nem avançar o cursor nesse caso. É sempre assim. Veja os caixas eletrônicos por exemplo...

 

Sobre ordena()

 

Tempos atrás eu postei um programa que faz isso de 4 maneiras, e uma com uma animação, umas barrinhas coloridas, Acho que se você ver rodando vai entender onde seu loop falha. E de todo modo lá tem funções que fazem isso. O programa está nesse endereço https://github.com/ARFNeto-CH/ch-191128-bubble e roda em Windows

 

Eis um desenho: o azul é o que já classificou, as comparações são os pares em amarelo. Meigo :) 

 

image.png.84ca7e9f38ea47f4b042964441e4cf4d.png

 

 

 

  • Obrigado 1
Postado
5 horas atrás, arfneto disse:

Eu realmente não entendo esse lance de registro por referência de que fala

Eu programo a 5 semanas(Isso, só exercícios básicos), o que eu quis dizer é que, nunca mexi com manipulação de registros em funções, no máximo, fiz exercícios de registrar alguém no próprio main().

 

 

 

 

5 horas atrás, arfneto disse:

O programa está nesse endereço

Ontem eu entendi o porque estava dando bug, por causa dessa linha abaixo:

 

13 horas atrás, arfneto disse:

Para que você acha que eram as variáveis cad->limite e cad->total?

.

 

 

Vou ver esse programa no GitHub. 

 

Obrigado@arfneto  por ter essa paciência ai pra ensinar. Vou aplicar!

Logo logo venho com mais dúvidas, porque vou aumentar esse código. :D

 

 

 

 

Postado
35 minutos atrás, Luiz Paulo Escobar disse:

Eu programo a 5 semanas(Isso, só exercícios básicos), o que eu quis dizer é que, nunca mexi com manipulação de registros em funções, no máximo, fiz exercícios de registrar alguém no próprio main()

 

Vai se sair bem. Escreveu um bom código para quem programa há semanas apenas.

 

No entanto recomendo entender que cada linha de um programa tem um sentido ou não deveria estar lá.

Então não escreva sem saber o que é.

Recomendo muito ter um livro ou mais. E alguma referência, um site como  o Tutorial's Point ou o Geeks For Geeks. E frequentar forums como esse ou o StackOverflow.

E ter amigos que programam ou gostam de programar também ajuda muito.

 

40 minutos atrás, Luiz Paulo Escobar disse:

Ontem eu entendi o porque estava dando bug, por causa dessa linha abaixo:

 

 

 

 

Muito bem!

 

Teste seu programa com aquele de 4 linhas que te mostrei. Não perca tempo.

Não sou um cara político, de opinião. O que eu escrevo aqui é em geral o padrão da indústria e da academia há décadas. Teste seu programa em partes. Use o que já tem, como as 2 funções que recebeu. Incorpore a terceira, que ordena, e teste sua função nova em um programa de 4 linhas... Que eu também já te mostrei.

 

 

  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...