strcmp [RESOLVIDO]

1. strcmp [RESOLVIDO]

ian cléver sales fernandes
ianclever

(usa Arch Linux)

Enviado em 06/06/2013 - 10:26h

gente estou fazendo um programa para efetuar o cadastro de até 10 pessoas depois gerar um relatório com quantos maiores de idade, quantos do sexo masculino e feminino, quantos moram em gurupi, e o total de clientes cadastrados. Obs.: os cpf's ' e codigos não podem ser iguais.
Pois é já fiz o programa inteiro, li, li denovo e não achei o que pode estar ocasionando, por mais que eu digite gurupi certo não esta entrando na comparação, eu dei um printf no strcmp e ele esta retornando 10 era para retornar 0, então não estou entendendo o porque disso, alguém pode me ajudar a solucionar?
fica na função 'conferir_gurupi':


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

typedef struct cliente
{
int cod,anoNascimento;
char cpf[11],nome[100],cidade[75],sexo;
}Cliente;
Cliente cliente[10];
int i,cont,cont2;

void zerar()
{
for(i=0;i<10;i++)
{
cliente[i].cod=0;
cliente[i].anoNascimento=0;
strcpy(cliente[i].cpf," ");
}
}
void cadastrar()
{
int aux,aux2,j;
char aux3[11];
for(i=0;i<10;i++)
{
if(cliente[i].cod==0)
{
printf("\nDigite o nome do cliente: ");
fgets(cliente[i].nome,100,stdin);
__fpurge(stdin);
do
{
cont=0;
cont2=0;
printf("\nDigite o código do cliente: ");
scanf("%d",&aux2);
__fpurge(stdin);
printf("\nDigite o cpf do cliente: ");
fgets(aux3,11,stdin);
__fpurge(stdin);
for(j=0;j<10;j++)
{
if(aux2==cliente[j].cod)
{
cont++;
}
if(strcmp(aux3,cliente[j].cpf)==0)
{
cont2++;
}
}
if(cont>0)
{
printf("\n já existe um cliente com esse código!");
}
if(cont2>0)
{
printf("\n já existe um cliente com esse cpf!");
}
if((cont==0)&&(cont2==0))
{
cliente[i].cod=aux2;
strcpy(cliente[i].cpf,aux3);
}
}while((cont!=0)&&(cont2!=0));
printf("\nDigite o sexo [m/f]: ");
scanf("%c",&cliente[i].sexo);
__fpurge(stdin);
printf("\nDigite o ano de nascimento: ");
scanf("%d",&cliente[i].anoNascimento);
__fpurge(stdin);
printf("\nDigite a cidade: ");
fgets(cliente[i].cidade,75,stdin);
__fpurge(stdin);
break;
}
}

}
void listar()
{
for(i=0;i<10;i++)
{
if(cliente[i].cod!=0)
{
printf("\nnome: %s",cliente[i].nome);
printf("\nsexo: %c",cliente[i].sexo);
printf("\ncodigo: %d",cliente[i].cod);
printf("\ncpf: %s",cliente[i].cpf);
printf("\nano de nascimento: %d",cliente[i].anoNascimento);
printf("\ncidade: %s",cliente[i].cidade);
printf("\n____________________________________________________________________________");
}
}
}
void maiores_idade()
{
int cont;
cont=0;
for(i=0;i<10;i++)
{
if((2013-cliente[i].anoNascimento>=18)&&(cliente[i].anoNascimento>0)&&(2013-cliente[i].anoNascimento<150))
{
cont++;
}
}
printf("\na)Existem %d maiores de idade cadastrados;",cont);
}
void sexo_masc_fem()
{
int cont,cont2;
cont=0;
cont2=0;
for(i=0;i<10;i++)
{
if((cliente[i].sexo=='m')||(cliente[i].sexo=='M'))
{
cont++;
}
if((cliente[i].sexo=='f')||(cliente[i].sexo=='F'))
{
cont2++;
}
}
printf("\nb)Existem %d pessoas do sexo masculino cadastradas e \n %d do sexo feminino;",cont,cont2);
}
void conferir_gurupi()
{
cont=0;
int a;
for(i=0;i<10;i++)
{
if((strcmp(cliente[i].cidade,"GURUPI")==0)||(strcmp(cliente[i].cidade,"Gurupi")==0)||(strcmp(cliente[i].cidade,"gurupi")==0))
{
cont++;
}
}
printf("\nc) %d pessoas cadastradas moram em gurupi;",cont);
}
void total()
{
int cont;
cont=0;
for(i=0;i<10;i++)
{
if(cliente[i].cod!=0)
{
cont++;
}
}
printf("\nd)Existem %d pessoas cadastradas",cont);
}
void relatorio()
{
maiores_idade();
sexo_masc_fem();
conferir_gurupi();
total();
}
void menu()
{
int opc;
do
{
printf("\n|>>>>>>>>>>>>>>>>>>>MENU<<<<<<<<<<<<<<<<<<<<<<|");
printf("\n|> <|");
printf("\n|> 1) Cadastrar; <|");
printf("\n|> 2) Listar; <|");
printf("\n|> 3) Relatório; <|");
printf("\n|> 4) Limpar tela; <|");
printf("\n|> 5) Sair; <|");
printf("\n|>>>>>>>>>>>>>>>>>>>MENU<<<<<<<<<<<<<<<<<<<<<<|");
printf("\n\nDigite uma opção: ");
scanf("%d",&opc);
__fpurge(stdin);
switch(opc)
{
case 1:
cadastrar();
break;
case 2:
listar();
break;
case 3:
relatorio();
break;
case 4:
system("clear");
break;
case 5:
break;
default :
printf("\nNão costa na lista!");
break;
}
}
while(opc!=5);
}
void main()
{
zerar();
menu();
}



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 06/06/2013 - 15:23h

O valor 10 retornado por strcmp() corresponde à diferença entre o '\n' no final da string lida com fgets() e a string desejada, que não possui essa marca de fim de linha ('\n'-0==10, donde '\n'==10, pelo menos enquanto se usar ASCII).

fgets() não remove a marca de fim linha -- e eu disse isto ontem mesmo noutra mensagem aqui neste fórum (http://www.vivaolinux.com.br/topico/C-C++/Lendo-scanf) -- para que quem lê possa saber se a leitura terminou porque se chegou ao fim da linha ou porque ocorreu algo que impedisse a leitura de futuros caracteres. Essa outra condição pode ser devida a se ter atingido o tamanho máximo do buffer, mas também por alguma situação inesperada, como fim de arquivo (EOF) prematuro, ou algum tipo de erro.

gets(), além de obsoleta, é insegura por não limitar a quantidade de caracteres lidos, e não oferece uma forma de perceber os mesmos erros cuja detecção fgets() permite. gets() não deve ser usada em hipótese alguma, mesmo onde não tiver sido ainda removida.

A outra possibilidade apontada, scanf(), é melhor. Mas é muito mais complexa. Eu recomendo enormemente que se leia uma documentação decente dessa função (a manpage do linux é decente, mas não tem exemplos práticos de uso de todos os casos -- até porque seriam muitíssimos --, de modo que é necessário ler com muita atenção). Na mesma mensagem que eu mencionei acima há também um exemplo de uso (mais ou menos) seguro de usar scanf() para ler strings.

3. Re: strcmp [RESOLVIDO]

Luis R. C. Silva
luisrcs

(usa Linux Mint)

Enviado em 06/06/2013 - 10:42h

Especifique o erro. ocorre no cadastro? no relatório? Em que momento a função é chamada? Que erro retorna? Se não retorna erro, o que retorna realmente?


4. Re: strcmp [RESOLVIDO]

ian cléver sales fernandes
ianclever

(usa Arch Linux)

Enviado em 06/06/2013 - 10:49h

rei_astro escreveu:

Especifique o erro. ocorre no cadastro? no relatório? Em que momento a função é chamada? Que erro retorna? Se não retorna erro, o que retorna realmente?


ocorre no relatório na parte:

*Quantos moram em gurupi - // está mostrando sempre
0 por mais que eu digite 'gurupi','GURUPI' ou 'Gurupi',aqui o erro é o retorno de strcmp que está sendo 10 enquanto deveria ser 0, aí se eu colocar para comparar como maior que 0 tudo que for maior vai entrar na comparação

mas a comparação está na função conferir_gurupi, que é chamada pelo relatório e o relatório é chamado pelo menu que depois é chamado pelo main



5. Re: strcmp [RESOLVIDO]

Luis R. C. Silva
luisrcs

(usa Linux Mint)

Enviado em 06/06/2013 - 12:01h

O problema está na codificação usada no fgets. Mesmo aparecendo o mesmo nome, os códigos são diferentes e retornam como se as strings fossem diferentes.

Se você usar o gets() para receber os nomes das cidades o problema se resolve, apesar de que é uma função em desuso, mas funciona.

Testei aqui e deu certo.


6. Re: strcmp [RESOLVIDO]

ian cléver sales fernandes
ianclever

(usa Arch Linux)

Enviado em 06/06/2013 - 12:42h

rei_astro escreveu:

O problema está na codificação usada no fgets. Mesmo aparecendo o mesmo nome, os códigos são diferentes e retornam como se as strings fossem diferentes.

Se você usar o gets() para receber os nomes das cidades o problema se resolve, apesar de que é uma função em desuso, mas funciona.

Testei aqui e deu certo.


esse que é problema, não sei no Debian, mas aqui no gcc do kubuntu o gets já não é mais reconhecido, foi tirado de circulação, por isso o uso do fgets.

qual seria a sintaxe correta do fgets para funcionar? ou outra função.


7. Re: strcmp [RESOLVIDO]

Diego Langer
dlanger

(usa Debian)

Enviado em 06/06/2013 - 13:33h

Em substituição ao comando gets(variavel), utilizo scanf("%s", variavel).


8. Re: strcmp [RESOLVIDO]

ian cléver sales fernandes
ianclever

(usa Arch Linux)

Enviado em 06/06/2013 - 13:39h

dlanger escreveu:

Em substituição ao comando gets(variavel), utilizo scanf("%s", variavel).


é, provisóriamente funcionou, porém não gosto muito de usar o scanf para isso pq ele não se dá muito bem com as strings. Se tiver outra função que vcs possam me passar...


9. Re: strcmp [RESOLVIDO]

ian cléver sales fernandes
ianclever

(usa Arch Linux)

Enviado em 06/06/2013 - 17:08h

paulo1205 escreveu:

O valor 10 retornado por strcmp() corresponde à diferença entre o '\n' no final da string lida com fgets() e a string desejada, que não possui essa marca de fim de linha ('\n'-0==10, donde '\n'==10, pelo menos enquanto se usar ASCII).

fgets() não remove a marca de fim linha -- e eu disse isto ontem mesmo noutra mensagem aqui neste fórum (http://www.vivaolinux.com.br/topico/C-C++/Lendo-scanf) -- para que quem lê possa saber se a leitura terminou porque se chegou ao fim da linha ou porque ocorreu algo que impedisse a leitura de futuros caracteres. Essa outra condição pode ser devida a se ter atingido o tamanho máximo do buffer, mas também por alguma situação inesperada, como fim de arquivo (EOF) prematuro, ou algum tipo de erro.

gets(), além de obsoleta, é insegura por não limitar a quantidade de caracteres lidos, e não oferece uma forma de perceber os mesmos erros cuja detecção fgets() permite. gets() não deve ser usada em hipótese alguma, mesmo onde não tiver sido ainda removida.

A outra possibilidade apontada, scanf(), é melhor. Mas é muito mais complexa. Eu recomendo enormemente que se leia uma documentação decente dessa função (a manpage do linux é decente, mas não tem exemplos práticos de uso de todos os casos -- até porque seriam muitíssimos --, de modo que é necessário ler com muita atenção). Na mesma mensagem que eu mencionei acima há também um exemplo de uso (mais ou menos) seguro de usar scanf() para ler strings.


boa, não sabia dessa do \n no fim, eu coloquei o \n no fim e aí comparou corretamente.


10. Re: strcmp [RESOLVIDO]

ian cléver sales fernandes
ianclever

(usa Arch Linux)

Enviado em 06/06/2013 - 17:09h

o resultado ficou assim:


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

typedef struct cliente
{
int cod,anoNascimento;
char cpf[11],nome[100],cidade[75],sexo;
}Cliente;
Cliente cliente[10];
int i,cont,cont2;

void zerar()
{
for(i=0;i<10;i++)
{
cliente[i].cod=0;
cliente[i].anoNascimento=0;
strcpy(cliente[i].cpf," ");
}
}
void cadastrar()
{
int aux,aux2,j;
char aux3[11];
for(i=0;i<10;i++)
{
if(cliente[i].cod==0)
{
printf("\nDigite o nome do cliente: ");
fgets(cliente[i].nome,100,stdin);
__fpurge(stdin);
do
{
cont=0;
cont2=0;
printf("\nDigite o código do cliente: ");
scanf("%d",&aux2);
__fpurge(stdin);
printf("\nDigite o cpf do cliente: ");
fgets(aux3,11,stdin);
__fpurge(stdin);
for(j=0;j<10;j++)
{
if(aux2==cliente[j].cod)
{
cont++;
}
if(strcmp(aux3,cliente[j].cpf)==0)
{
cont2++;
}
}
if(cont>0)
{
printf("\n já existe um cliente com esse código!");
}
if(cont2>0)
{
printf("\n já existe um cliente com esse cpf!");
}
if((cont==0)&&(cont2==0))
{
cliente[i].cod=aux2;
strcpy(cliente[i].cpf,aux3);
}
}while((cont!=0)&&(cont2!=0));
printf("\nDigite o sexo [m/f]: ");
scanf("%c",&cliente[i].sexo);
__fpurge(stdin);
printf("\nDigite o ano de nascimento: ");
scanf("%d",&cliente[i].anoNascimento);
__fpurge(stdin);
printf("\nDigite a cidade: ");
fgets(cliente[i].cidade,75,stdin);
__fpurge(stdin);
break;
}
}

}
void listar()
{
for(i=0;i<10;i++)
{
if(cliente[i].cod!=0)
{
printf("\nnome: %s",cliente[i].nome);
printf("\nsexo: %c",cliente[i].sexo);
printf("\ncodigo: %d",cliente[i].cod);
printf("\ncpf: %s",cliente[i].cpf);
printf("\nano de nascimento: %d",cliente[i].anoNascimento);
printf("\ncidade: %s",cliente[i].cidade);
printf("\n____________________________________________________________________________");
}
}
}
void maiores_idade()
{
int cont;
cont=0;
for(i=0;i<10;i++)
{
if((2013-cliente[i].anoNascimento>=18)&&(cliente[i].anoNascimento>0)&&(2013-cliente[i].anoNascimento<150))
{
cont++;
}
}
printf("\na)Existem %d maiores de idade cadastrados;",cont);
}
void sexo_masc_fem()
{
int cont,cont2;
cont=0;
cont2=0;
for(i=0;i<10;i++)
{
if((cliente[i].sexo=='m')||(cliente[i].sexo=='M'))
{
cont++;
}
if((cliente[i].sexo=='f')||(cliente[i].sexo=='F'))
{
cont2++;
}
}
printf("\nb)Existem %d pessoas do sexo masculino cadastradas e \n %d do sexo feminino;",cont,cont2);
}
void conferir_gurupi()
{
cont=0;
int a;
for(i=0;i<10;i++)
{
if((strcmp(cliente[i].cidade,"GURUPI\n")==0)||(strcmp(cliente[i].cidade,"Gurupi\n")==0)||(strcmp(cliente[i].cidade,"gurupi\n")==0))
{
cont++;
}
}
printf("\nc) %d pessoas cadastradas moram em gurupi;",cont);
}
void total()
{
int cont;
cont=0;
for(i=0;i<10;i++)
{
if(cliente[i].cod!=0)
{
cont++;
}
}
printf("\nd)Existem %d pessoas cadastradas",cont);
}
void relatorio()
{
maiores_idade();
sexo_masc_fem();
conferir_gurupi();
total();
}
void menu()
{
int opc;
do
{
printf("\n|>>>>>>>>>>>>>>>>>>>MENU<<<<<<<<<<<<<<<<<<<<<<|");
printf("\n|> <|");
printf("\n|> 1) Cadastrar; <|");
printf("\n|> 2) Listar; <|");
printf("\n|> 3) Relatório; <|");
printf("\n|> 4) Limpar tela; <|");
printf("\n|> 5) Sair; <|");
printf("\n|>>>>>>>>>>>>>>>>>>>MENU<<<<<<<<<<<<<<<<<<<<<<|");
printf("\n\nDigite uma opção: ");
scanf("%d",&opc);
__fpurge(stdin);
switch(opc)
{
case 1:
cadastrar();
break;
case 2:
listar();
break;
case 3:
relatorio();
break;
case 4:
system("clear");
break;
case 5:
break;
default :
printf("\nNão costa na lista!");
break;
}
}
while(opc!=5);
}
void main()
{
zerar();
menu();
}



11. Re: strcmp [RESOLVIDO]

ian cléver sales fernandes
ianclever

(usa Arch Linux)

Enviado em 06/06/2013 - 17:19h

e obrigado a todos que me ajudaram.


12. Re: strcmp [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 06/06/2013 - 17:29h

Você fez o oposto do que eu acho que deveria. Seria melhor você remover o '\n' do final da string, pois ele não agrega informação útil para um cadastro. Imagine um milhão de registros, cada um deles ocupando um byte a mais do que poderia na hora de registrar a cidade, só para acomodar um milhão de '\n's que não agregam informação nenhuma ao endereço. Fora a inconsistência na hora de tratar cidades que, dependendo do tamanho do nome, podem ter o '\n' ou não.ao nome da cidade.



01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts