Ir para conteúdo

POWERED BY:

Arquivado

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

Isadora Maria Mendes

Problemas ao colocar struct em ordem alfabetica

Recommended Posts

Pessoal, estou fazendo um laboratorio de programação, e eu estou com um problema na hora de por os meus registros em ordem alfabética...

O programa é esse

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

#define TAM 100

struct Cardapio{
   char nome[20];
   float preco;
   short usado;
};

typedef struct Cardapio Cardapio;


//faz com que todas posicoes do vetor fiquem vagas
void iniciaCadastro(Cardapio vet[], int tam){
 int i;

 for(i=0; i<tam; i++)
 {
   vet[i].usado = 0;
 }
}

//imprime o menusinho
void imprimeMenu(){
 printf("0: sair do programa.\n");
 printf("1: inserir um prato no cardapio.\n");
 printf("2: remove um prato do cardapio.\n");
 printf("3: lista os pratos em ordem alfabetica crescente de nome\n");
 printf("4: lista os pratos em ordem crescente de preco\n");
}

//le os dados de um unico prato
void lePrato (Cardapio *p)
{
   fprintf(stderr, "Digite o nome do prato:");
   scanf("%s", &(*p).nome);
   getchar();

   fprintf(stderr, "Digite o preco do prato:");
   scanf("%lf", &(*p).preco);
   getchar();
}

//insere um prato
int inserePrato(Cardapio vet[], int tam, Cardapio p){
   int i;

   for(i=0; i<100; i++){
       if(vet[i].usado == 0){ //se posicao i estiver vaga
           vet[i] = p;
           vet[i].usado = 1; //posicao i passa a estar usada
           return 1;
       }
   }
   return 0; //cadastro está cheio
}

//remove um prato
int removePrato(Cardapio vet[], int tam, char nome[]){
   int i;

   for(i=0; i<tam; i++){
       //strcmp retorna 0 se as 2 strings parametros forem iguais
       if(strcmp(vet[i].nome, nome) == 0){ 
           vet[i].usado = 0; //posicao i fica vaga
           return 1;
       }
   }
   return 0; //prato não está cadastrado
}

//ordena o vetor
void ordemA(Cardapio nome[], int tam){
   char aux;
   int i = 0, j;

   for(j=1; j<tam; j++)
   {
       aux = nome[j].nome;
       i = j-1;
       while(i >= 0 && strcmp(nome[i].nome,aux) > 0)
       {
           nome[i+1].nome = nome[i].nome;
           i--;
       }
       nome[i+1].nome = aux;
       }
}
//funcao que imprime um unico prato
void imprimePrato(Cardapio p){
 printf(" %-20s\n",p.nome);
 printf("%6.2f\n", p.preco);
}

//funcao que imprime todos os pratos de um vetor
void imprimePratos(Cardapio vet[], int tam){
 int i;
 for(i=0; i<tam; i++){
   if(vet[i].usado == 1){ //se posicao i conter algo valido entao imprime
     imprimePrato(vet[i]);
   }
 }
}

int main(){
 Cardapio pratos[TAM]; //pode-se armazenar até 100 pratos
 Cardapio p;
 int opcao=1, aux;
 char nome[20];

 iniciaCadastro(pratos, TAM);

 do{
     imprimeMenu();
     scanf("%d", &opcao);    
//ok
     if(opcao == 1)
     {

         lePrato(&p);
         aux = inserePrato(pratos, TAM, p);

         if(aux)
             fprintf(stderr, "Prato cadastrado com sucesso!\n\n");
     }
//ok      
     if(opcao == 2)
     {

         fprintf(stderr, "Digite o nome do prato\n");
         scanf("%s", nome);

         aux = removePrato(pratos, TAM, nome);

         if(aux)           
             fprintf(stderr, "Prato removido com sucesso!\n\n");
         else
             printf("Erro: prato nao encontrado.\n");
     }

     if (opcao == 3)
     {
     ordemA(pratos, TAM);
     imprimePratos(pratos, TAM);
     break;
     }
     if (opcao == 4)
     {
         /*
     imprimeFrutas(frutas, TAM);
     break;*/
     }
//ok     
     if(opcao == 0)
     {
         return 0;
     }


     if((opcao != 0) && (opcao != 1) && (opcao != 2) && (opcao != 3) && (opcao != 4))
     {
         printf("Erro: opcao invalida.\n");
     }

 }while(opcao != 0);

}

 

E quando eu compilo aparece o seguinte erro:

main.c: In function 'lePrato':

main.c:39: warning: format '%s' expects type 'char *', but argument 2 has type 'char (*)[20]'

main.c:39: warning: format '%s' expects type 'char *', but argument 2 has type 'char (*)[20]'

main.c:43: warning: format '%lf' expects type 'double *', but argument 2 has type 'float *'

main.c:43: warning: format '%lf' expects type 'double *', but argument 2 has type 'float *'

main.c: In function 'ordemA':

main.c:82: warning: assignment makes integer from pointer without a cast

main.c:84: warning: passing argument 2 of 'strcmp' makes pointer from integer without a cast

main.c:86: error: incompatible types in assignment

main.c:89: error: incompatible types in assignment

 

A minha principal dúvida está com a função ordemA, pois, ao meu ver (de que começou a programar esses dias) tá tudo ok. Me ajudem?

Grata

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isadora,

 

Não cheguei a testar a lógica da ordenação, pois creio que esteja correto.

 

Na função, há alguns erros de como tratar os tipos de dados.

 

1)

char aux;
...
aux = nome[j].nome;

 

Qual o intuito da variável aux? Você declarou ela como char, caracter de um byte, e tentou atribuir a ela uma string de vários bytes.

Se a intenção era atribuir a primeira letra da string, por exemplo, devereia ter feito algo parecido com isso:

nome[i+1].nome = nome[i].nome[0];

 

2) Em C, você não pode fazer atribuições de strings apenas utilizando o operador "=".

Deve utilizar as funções da biblioteca string.h do C, strcpy ou strncpy que é mais segura.

Segue o link com informações da biblioteca:

http://www.cplusplus.com/reference/clibrary/cstring/

 

3) Um erro de lógica:

while(i >= 0 && strcmp(nome[i].nome,aux) > 0)
       {
           nome[i+1].nome = nome[i].nome;
           i--;
       }

Neste while, você está deslocando os registros . Mas perceba que faz apenas com as strings da estrutura que declarou, esquecendo os demais dados. Isso poderá causar perda de dados ou uma tremenda confusão entre eles.

 

Espero ter ajudado, FLW! :grin:

Compartilhar este post


Link para o post
Compartilhar em outros sites

GBecker,

Tentei arrumar tudo que você disse, e passou a compilar, eu estava errando feio umas coisas,

Porém, a função agora imprime lixo. Você poderia me ajudar?

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

#define TAM 100

struct Cardapio{
   char nome[20];
   float preco;
   short usado;
};

typedef struct Cardapio Cardapio;


//faz com que todas posicoes do vetor fiquem vagas
void iniciaCadastro(Cardapio vet[], int tam){
 int i;

 for(i=0; i<tam; i++)
 {
   vet[i].usado = 0;
 }
}

//imprime o menusinho
void imprimeMenu(){
 printf("0: sair do programa.\n");
 printf("1: inserir um prato no cardapio.\n");
 printf("2: remove um prato do cardapio.\n");
 printf("3: lista os pratos em ordem alfabetica crescente de nome\n");
 printf("4: lista os pratos em ordem crescente de preco\n");
}

//le os dados de um unico prato
void lePrato (Cardapio *p)
{
   fprintf(stderr, "Digite o nome do prato:");
   scanf("%s", &(*p).nome);
   getchar();

   fprintf(stderr, "Digite o preco do prato:");
   scanf("%lf", &(*p).preco);
   getchar();
}

//insere um prato
int inserePrato(Cardapio vet[], int tam, Cardapio p){
   int i;

   for(i=0; i<100; i++){
       if(vet[i].usado == 0){ //se posicao i estiver vaga
           vet[i] = p;
           vet[i].usado = 1; //posicao i passa a estar usada
           return 1;
       }
   }
   return 0; //cadastro está cheio
}

//remove um prato
int removePrato(Cardapio vet[], int tam, char nome[]){
   int i;

   for(i=0; i<tam; i++){
       //strcmp retorna 0 se as 2 strings parametros forem iguais
       if(strcmp(vet[i].nome, nome) == 0){ 
           vet[i].usado = 0; //posicao i fica vaga
           return 1;
       }
   }
   return 0; //prato não está cadastrado
}

//ordena o vetor
Cardapio pratos[100];
void ordemA(int tam, Cardapio vetor[]){
   Cardapio aux;
   int i, j;
   for(i = 1; i < tam; i++) {
       for(j = i; j > 0; j--) {
           if(strcmp(vetor[j].nome, vetor[j-1].nome)<0){
             strcpy(aux.nome,vetor[j].nome);
             aux.preco = vetor[j].preco;
             strcpy(vetor[j].nome,vetor[j-1].nome);
             vetor[j].preco = vetor[j-1].preco;
             strcpy(vetor[j-1].nome,aux.nome);
             vetor[j-1].preco = aux.preco;
           }
       }
   }
}
//ordena do menor valor pro maior
void bubbleSort(Cardapio vet[], int tam){
   int i, j;
   Cardapio aux;
   for(i=0; i<tam; i++)
   {
       for(j=0; j < tam-1; j++) 

           if(vet[j].preco > vet[j+1].preco){
               aux.preco = vet[j].preco;
               strcpy(aux.nome,vet[j].nome);
               vet[j].preco = vet[j+1].preco;
               strcpy(vet[j].nome,vet[j-1].nome);
               vet[j+1].preco = aux.preco;
               strcpy(vet[j-1].nome,aux.nome);
           }

   }

}

//funcao que imprime um unico prato
void imprimePrato(Cardapio p){
   int i;
   printf("%-20s%6.2f\n",p.nome, p.preco);
}

//funcao que imprime todos os pratos de um vetor
void imprimePratos(Cardapio vet[], int tam){
 int i;
 for(i=0; i<tam; i++){
   if(vet[i].usado == 1){ //se posicao i conter algo valido entao imprime
     imprimePrato(vet[i]);
   }
 }
}

int main(){
 Cardapio pratos[TAM]; //pode-se armazenar até 100 pratos
 Cardapio p;
 int opcao=1, aux;
 char nome[20];

 iniciaCadastro(pratos, TAM);

 do{
     imprimeMenu();
     scanf("%d", &opcao);    
//ok
     if(opcao == 1)
     {

         lePrato(&p);
         aux = inserePrato(pratos, TAM, p);

         if(aux)
             fprintf(stderr, "Prato cadastrado com sucesso!\n\n");
     }
//ok      
     if(opcao == 2)
     {

         fprintf(stderr, "Digite o nome do prato\n");
         scanf("%s", nome);

         aux = removePrato(pratos, TAM, nome);

         if(aux)           
             fprintf(stderr, "Prato removido com sucesso!\n\n");
         else
             printf("Erro: prato nao encontrado.\n");
     }

     if (opcao == 3)
     {
     ordemA(TAM, pratos);
     imprimePratos(pratos, TAM);
     break;
     }
     if (opcao == 4)
     {
         bubbleSort(pratos, TAM);
         imprimePratos(pratos, TAM);

     }
//ok     
     if(opcao == 0)
     {
         return 0;
     }


     if((opcao != 0) && (opcao != 1) && (opcao != 2) && (opcao != 3) && (opcao != 4))
     {
         printf("Erro: opcao invalida.\n");
     }

 }while(opcao != 0);

}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ainda existem alguns problemas:

 

Na função lePrato, você passa &(*p).nome como argumento que deve ter tipo (char *), mas tem tipo (char (*)[20]). Ou seja, ao invés de um ponteiro para char, está passando um ponteiro para um vetor de 20 chars. Sugiro que passe (*p).nome ou p->nome.

 

Ainda na lePrato, você usa o formato %lf para ler um (float). O formato correto é %f.

 

Na imprimePrato, o objeto de nome i não é utilizado.

 

Na inserePrato, você não está usando o parâmetro tam. Ao invés disso, usa o literal 100. Sugiro que use tam.

 

Sugiro que reveja também suas ordenações. Há erros de lógica que estão causando as impressões erradas às quais você se refere.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oii guidjos :rolleyes: ,

Obrigada pela ajuda.

Tentei concertar tudo o que você disse, e testei isoladamente a função ordemA, depois de fazer alterações nela, e ela funcionou... Só que o problema continua, ela isolada, funciona, ela no programa completo não...

Pensei na possibilidade de ser na função inserePrato e imprimePrato. Fiz alterações, e testando no papel, era pra funcionar.

Segue o novo código:

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

#define TAM 100

struct Cardapio{
   char nome[20];
   float preco;
   short usado;
};

typedef struct Cardapio Cardapio;

//imprime o menusinho
void imprimeMenu(){
 printf("0: sair do programa.\n");
 printf("1: inserir um prato no cardapio.\n");
 printf("2: remove um prato do cardapio.\n");
 printf("3: lista os pratos em ordem alfabetica crescente de nome\n");
 printf("4: lista os pratos em ordem crescente de preco\n");
}

//faz com que todas posicoes do vetor fiquem vagas
void iniciaCadastro(Cardapio vet[], int tam){
 int i;

 for(i=0; i<tam; i++)
 {
   vet[i].usado = 0;
 }
}

//insere um prato
int inserePrato(Cardapio vet[], int tam){
   int i;

   for(i=0; i<tam; i++){
       if(vet[i].usado == 0){ //se posicao i estiver vaga

           fprintf(stderr, "Digite o nome do prato:");
           scanf("%s", ((vet[i]).nome));

           fprintf(stderr, "Digite o preco do prato:");
           scanf("%f", &((vet[i]).preco));

           vet[i].usado = 1; //posicao i passa a estar usada
           return 1;
       }
       else
           continue;
   }
   return 0; //cadastro está cheio
}

//remove um prato
int removePrato(Cardapio vet[], int tam, char nome[]){
   int i;

   for(i=0; i<tam; i++){
       //strcmp retorna 0 se as 2 strings parametros forem iguais
       if(strcmp(vet[i].nome, nome) == 0){ 
           vet[i].usado = 0; //posicao i fica vaga
           return 1;
       }
   }
   return 0; //prato não está cadastrado
}

//ordena o vetor
void ordemA(int tam, Cardapio vetor[])
{
   Cardapio aux;
   Cardapio aux1;
   int i, j;
   for(i = 1; i < tam; i++)
   {
       for(j = i; j > 0; j--)
       {
           if(strcoll(vetor[j].nome, vetor[j-1].nome) < 0)
           {
             strcpy(aux.nome,vetor[j].nome);
             aux1.preco = vetor[j].preco;

             strcpy(vetor[j].nome,vetor[j-1].nome);
             vetor[j].preco = vetor[j-1].preco;

             strcpy(vetor[j-1].nome,aux.nome);
             vetor[j-1].preco = aux1.preco;

           }
       }
   }
}

//funcao que imprime todos os pratos de um vetor
void imprimePratos(Cardapio vet[], int tam){
 int i;
 for(i=0; i<tam; i++)
 {
   if(vet[i].usado == 1)
   { //se posicao i conter algo valido entao imprime
     printf("%s - %f\n",vet[i].nome, vet[i].preco);
   }
   else
       continue;
 }
}

int main(){
 Cardapio pratos[TAM]; //pode-se armazenar até 100 pratos
 int opcao=1, a;
 char nome[20];

 iniciaCadastro(pratos, TAM);

 do{
     imprimeMenu();
     scanf("%d", &opcao);    
//ok
     if(opcao == 1)
     {

         a = inserePrato(pratos, TAM);

         if(a)
             fprintf(stderr, "Prato cadastrado com sucesso!\n\n");
     }
//ok      
     if(opcao == 2)
     {

         fprintf(stderr, "Digite o nome do prato\n");
         scanf("%s", nome);

         a = removePrato(pratos, TAM, nome);

         if(a)           
             fprintf(stderr, "Prato removido com sucesso!\n\n");
         else
             printf("Erro: prato nao encontrado.\n");
     }

     if (opcao == 3)
     {
     ordemA(TAM, pratos);
     imprimePratos(pratos, TAM);
     break;
     }
     if (opcao == 4)
     {
         imprimePratos(pratos, TAM);

     }
//ok     
     if(opcao == 0)
     {
         return 0;
     }


     if((opcao != 0) && (opcao != 1) && (opcao != 2) && (opcao != 3) && (opcao != 4))
     {
         printf("Erro: opcao invalida.\n");
     }

 }while(opcao != 0);

 return 0;
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ainda existem alguns problemas:

 

1. Na função de ordenação, você declara objetos com nomes aux1 e aux, e confunde o uso dos dois;

 

2. Ainda na ordenação, você percorre todos os elementos, não importando se estão ativos ou não. Ao tentar examinar o nome dos pratos cujos registros não foram ocupados, você gera undefined behavior (veja este material para entender do que se trata). A solução é inicializar todos os valores de todos os registros, inserindo para os nomes valores lexicográficos altos (que nunca serão considerados menores que nenhum outro nome pela strcoll). Se você copiar um valor 'pequeno' como "" (string 'vazia'), a ordenação vai fazer com que seus registros vão pros últimos lugares. Por não considerar este problema, você não lida com a transferência do flag de ocupação/desocupação de cada registro. Isto precisa ser considerado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, segui seus conselhos, e com a ajuda de um amigo, consegui fechar o programa.

O que você disse, guidjos, matou a pau, pois, não passava em alguns testes e era exatamente por ir pra final do registro que tava dando problema.

A quem interesse, o código final é esse:


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

#define TAM 100

typedef struct Cardapio{
   char nome[20];
   float preco;
   short usado;
}Cardapio;

//imprime o menusinho
void imprimeMenu(){
   fprintf(stderr, "0: sair do programa.\n");
   fprintf(stderr, "1: inserir um prato no cardapio.\n");
   fprintf(stderr, "2: remove um prato do cardapio.\n");
   fprintf(stderr, "3: lista os pratos em ordem alfabetica crescente de nome\n");
   fprintf(stderr, "4: lista os pratos em ordem crescente de preco\n");
}

//faz com que todas posicoes do vetor fiquem vagas
void iniciaCadastro(Cardapio vet[], int tam){
   int i;

   for(i=0; i<tam; i++)
   {
       vet[i].usado=0;
       strcpy(vet[i].nome, "~");
       vet[i].preco = 99999.0;


   }
}
//Le dados de um prato
void lePrato(Cardapio *f){

   //printf("Digite o nome:\n");
   scanf("%s", (*f).nome);
   getchar();

   //printf("Digite o preco:\n");
   scanf("%f", &(*f).preco);
   getchar();

}

//retorna 1 ou 0 dependendo se foi possível ou nao cadastrar a fruta
int inserePrato(Cardapio vet[], int tam, Cardapio f){
   int i;

   for(i=0; i<tam; i++){
       if(vet[i].usado == 0){ //se posicao i estiver vaga
           vet[i] = f;
           vet[i].usado = 1; //posicao i passa a estar usada
           return 1;
       }
   }
   return 0; //cadastro esta cheio
}

//remove um prato
int removePrato(Cardapio vet[], int tam, char nome[]){
   int i;

   for(i=0; i<tam; i++){
       //strcmp retorna 0 se as 2 strings parametros forem iguais
       if(strcmp(vet[i].nome, nome) == 0){ 
           vet[i].usado = 0; //posicao i fica vaga
    strcpy(vet[i].nome, "~");
    vet[i].preco = 99999.0;
           return 1;
       }    
   }
   return 0; //prato não está cadastrado
}

//ordena o vetor
void ordemA(int tam, Cardapio vetor[])
{
Cardapio aux;
int i, j;
for(i = 1; i < tam; i++)
{
	for(j = i; j > 0; j--)
	{
		//if((vetor[j].usado == 1) && (vetor[j-1].usado == 1)){
			if(strcoll(vetor[j].nome, vetor[j-1].nome) < 0)
			{
				strcpy(aux.nome,vetor[j].nome);
				aux.preco = vetor[j].preco;
				aux.usado = vetor[j].usado;

				strcpy(vetor[j].nome,vetor[j-1].nome);
				vetor[j].preco = vetor[j-1].preco;
				vetor[j].usado = vetor[j-1].usado;

				strcpy(vetor[j-1].nome,aux.nome);
				vetor[j-1].preco = aux.preco;
				vetor[j-1].usado = aux.usado;
			}
		//}
	}
}

}

//ordem numerica crescente
void ordemN(int tam, Cardapio vetor[])
{
Cardapio aux;
int i, j;
for(i = 1; i < tam; i++)
{
	for(j = i; j > 0; j--)
	{
		//if((vetor[j].usado == 1) && (vetor[j-1].usado == 1)){
			if(vetor[j].preco < vetor[j-1].preco)
			{
				strcpy(aux.nome,vetor[j].nome);
				aux.preco = vetor[j].preco;
				aux.usado = vetor[j].usado;

				strcpy(vetor[j].nome,vetor[j-1].nome);
				vetor[j].preco = vetor[j-1].preco;
				vetor[j].usado = vetor[j-1].usado;

				strcpy(vetor[j-1].nome,aux.nome);
				vetor[j-1].preco = aux.preco;
				vetor[j-1].usado = aux.usado;
			}
		//}
	}
}

}
//funcao que imprime todos os pratos de um vetor
void imprimePratos(Cardapio vet[], int tam){
   int i, cont=0;
   for(i=0; i<tam; i++)
   {
       if(vet[i].usado == 1)
       { //se posicao i conter algo valido entao imprime
           printf("%-20s %6.2f\n", vet[i].nome, vet[i].preco);  
       }
       else if(vet[i].usado == 0)
       {
           cont = cont + 1;
       }
   }
   if(cont==100)
   {
       printf("Erro: nenhum prato cadastrado.");
   }
}

int main(){
   Cardapio pratos[TAM]; //pode-se armazenar até 100 pratos
   Cardapio f;
   int opcao=1, a;
   char nome[20];

   iniciaCadastro(pratos, TAM);

   do{
       //imprimeMenu();
       scanf("%d", &opcao);    
       //ok
       if(opcao == 1)
       {

           lePrato(&f);
           inserePrato(pratos, TAM, f);
       }
       //ok      
       if(opcao == 2)
       {

           //fprintf(stderr, "Digite o nome do prato\n");
           scanf("%s", nome);

           a = removePrato(pratos, TAM, nome);

           if(a==0)
               printf("Erro: prato nao encontrado.\n");
       }

       if (opcao == 3)
       {
           ordemA(TAM, pratos);
           imprimePratos(pratos, TAM);
           printf("\n");
       }
       if (opcao == 4)
       {
           ordemN(TAM, pratos);
           imprimePratos(pratos, TAM);
           printf("\n");


       }
       //ok     
       if(opcao == 0)
       {
           return 0;
       }


       if((opcao != 0) && (opcao != 1) && (opcao != 2) && (opcao != 3) && (opcao != 4))
       {
           printf("Erro: opcao invalida.\n");
       }

   }while(opcao != 0);

   return 0;
}

Tem coisa que poderia melhorar, mas como ainda tenho que estudar cálculo, "é o que tem pra hoje" rsrs...

Agradeço a todos que colaboraram.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom não cheguei a olhar todo o código, mais de uma lida nesse comando: strcoll, eu lembro uma vez que precisei ordenar uns nomes e com ele deu certinho ;D

 

[]s

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.