Bug extremamente estranho nesse código em C

1. Bug extremamente estranho nesse código em C

adriano
afls3

(usa Ubuntu)

Enviado em 22/09/2010 - 16:51h

Olá pessoal!
Escrevi um programa que simula uma eleição à um cargo numa empresa.
São três candidatos: A, B e C;
Há a possibilidade de voto branco e voto nulo.
O problema é que eu criei um contador chamado n_n que deve contar o
número de votos nulos e ele simplesmente não é incrementado quando
o usuário digita 'n'.
Em algumas versões do CodeBlocks acontece outro problema: o programa
sai do laço for sem que a condição de saída seja satisfeita.
segue o código abaixo:
Código:

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


//Tem um bug extremamente estranho no programa
//Ele simplesmente não conta o número de votos nulos
//Tem um printf como comentário para testar que o
//código executa o trecho de código onde tem um comando
//de incremento do contador de votos nulos
int main()
{
int i;
int k;
int n_A = 0;//contador de votos para A
int n_B = 0;//contador de votos para B
int n_C = 0;//contador de votos para C
int n_b = 0;//contador de votos brancos
int n_n = 0;//contador de votos nulos
char ch;//armazenará o caractere digitado pelo usuário
int n_votantes;//número de votantes
int n_validos;//número de votos válidos
char vencedor = '0';//indica qual candidato venceu as eleições
//considerando que não há vencedor se há
//empate entre os mais votados

printf("Informe os votos da seguinte forma:\n");
printf("Digite 'A' se o voto é para o candidato A;\n");
printf("Digite 'B' se o voto é para o candidato B;\n");
printf("Digite 'C' se o voto é para o candidato C;\n");
printf("Digite 'b' se o voto é branco;\n");
printf("Digite 'n' se o voto é nulo;\n");
printf("Informe o numero de seccoes: ");
scanf("%d", &k);

for( i = 1 ; i <= k ; i++ ){

printf("dados da seccao %d\n", i);
do{
scanf("%s", &ch);
if( ch == 'A' ){
n_A++;
}
else if( ch == 'B' ){
n_B++;
}
else if( ch == 'C' ){
n_C++;
}
else if( ch == 'b' ){
n_b++;
}
else if( ch == 'n' ){
n_n++;
//printf("Entrou aqui!\n");
}
else if( ch != '0' ){
printf("Dado invalido! Informe os dados");
printf(" da forma especificada acima.\n");
}
} while( ch != '0' );

}
//cálculo do número de votantes e de votos válidos
n_votantes = n_A + n_B + n_C + n_b + n_n;
n_validos = n_A + n_B +n_C;
printf("Numero de votantes: %d\n", n_votantes);
printf("Numero de votos do candidato A: %d\n", n_A);
printf("Numero de votos do candidato B: %d\n", n_B);
printf("Numero de votos do candidato C: %d\n", n_C);
printf("Numero de votos brancos: %d\n", n_b);
printf("Numero de votos nulos: %d\n", n_n);
printf("Numero de votos validos: %d\n", n_validos);

//esses ifs fazem todas as combinações possíveis das
//comparações e imprime o resultado das comparações
if( n_A > n_B ){
if( n_A > n_C ){
printf("O Candidato A foi o mais votado.\n");
vencedor = 'A';
}
else if( n_A == n_C )
printf("Os Candidatos A e C foram os mais votados.\n");
else{
printf("O Candidato C foi o mais votado.\n");
vencedor = 'C';
}
}
else if( n_A == n_B ){
if( n_A > n_C )
printf("Os candidatos A e B foram os mais votados.\n");
else if( n_A == n_C)
printf("Os candidatos A, B e C receberam a mesma votacao.\n");
else{
printf("O candidato C foi o mais votado.\n");
vencedor = 'C';
}
}
else{
if( n_B > n_C ){
printf("O candidato B foi o mais votado.\n");
vencedor = 'B';
}
else if ( n_B == n_C )
printf("Os candidatos B e C foram os mais votados.\n");
else{
printf("O candidato C foi o mais votado.\n");
vencedor = 'C';
}
}

//decidindo se a eleição foi válida
if( (n_b + n_n) < n_validos )
printf("As eleicoes foram validas.\n");
else
printf("As eleicoes nao foram validas.\n");

//decidindo se haverá segundo turno
if((vencedor = 'A') && ( n_A > 0.5*n_validos )){
printf("Nao havera segundo turno.\n");
printf("O candidato A venceu as eleicoes!\n");
}
else if((vencedor = 'B') && ( n_B > 0.5*n_validos )){
printf("Nao havera segundo turno.\n");
printf("O candidato B venceu as eleicoes!\n");
}
else if((vencedor = 'C') && ( n_C > 0.5*n_validos )){
printf("Nao havera segundo turno.\n");
printf("O candidato C venceu as eleicoes!\n");
}
else
printf("Havera segundo turno.\n");

return 0;
}

Aguardo alguma ajuda.
Valeu!!!!!!


  


2. Re: Bug extremamente estranho nesse código em C

Ezequias Rocha
Ezequias Rocha

(usa Ubuntu)

Enviado em 22/09/2010 - 17:49h

Pode ser que o problema reside na leitura do dado inserido pelo usuário.
Tente ler o voto com a função getche(), presente em string.h (se não me engano). Caso não dê certo, alterne para outras funções de leitura de char inserido pelo usuário e vê se o erro persiste.

Embraces!


3. Re: Bug extremamente estranho nesse código em C

adriano
afls3

(usa Ubuntu)

Enviado em 22/09/2010 - 18:02h

Eu já usei getch, getche, getchar, fgets .... e não funciona.
Se eu trocar %s por %c também dá bronca.
Se você puder executar o código perceberá que scanf captura 'A', 'B', 'C' e 'n' mas
não captura 'n'.
Se, quando tu compilar, ele executar o laço sem problemas e imprimir tudo o que
aparece após o for verá que somente n_n não foi incrementado.
Se não for assim então só vai ser executado o primeiro laço do for.



4. Re: Bug extremamente estranho nesse código em C

Ezequias Rocha
Ezequias Rocha

(usa Ubuntu)

Enviado em 23/09/2010 - 08:16h

Tente outras saídas:
- Usar o contador como ponteiro (e. g. int *n_n; portanto (*n_n)++;)
- Mudar o tipo da variável n_n, exemplo, long n_n;
- Mude o nome da variável, exemplo, de n_n para Nro_n;
- Coloque dois contadores em paralelo, exemplo, Nro_n1 e Nro_n2, incrementando-os simultaneamente quando voto nulo, então veja se os dois, apenas um ou nenhum deles estão sendo incrementados;
- Crie uma estrutura para a contagem dos votos, exemplo:
typedef struct{
long N_A;
long N_B;
long N_C;
long N_b;
long N_n;
}Nro_votos;
e teste se ocorre o problema;
- Tente fazer a implementação usando números para a votação, exemplo:
printf("Informe os votos da seguinte forma:\n");
printf("Digite '1' se o voto é para o candidato A;\n");
printf("Digite '2' se o voto é para o candidato B;\n");
printf("Digite '3' se o voto é para o candidato C;\n");
printf("Digite '4' se o voto é branco;\n");
printf("Digite '5' se o voto é nulo;\n");
Assim sendo, a leitura será de inteiros, ao invés de char;
e, finalmente,
- Veja se não está usando nenhuma palavra reservada do ambiente que está usando, ou mesmo do ANSI C;

Embraces!


5. Problema da scanf

Lucas Priori
lpriori

(usa Slackware)

Enviado em 23/09/2010 - 09:32h

Aqui no meu funcionou perfeitamente.
Mas o problema é que você usa a scanf. Esta função não limpa o buffer de entrada e ai efeitos estranhos podem aparecer.

Troque as seguintes linhas:

scanf("%s", &ch);
por:
ch=getchar();

else if( ch != '0' ){
por
else if( ch != '0' && ch != 10){


Teste ai e verá que vai funcionar.

o '&& ch != 10' que adicionei neste ultimo if é para ele ignorar código 'ENTER' que será retornado com a getchar.

Espero ter ajudado.



6. resolvido!

adriano
afls3

(usa Ubuntu)

Enviado em 23/09/2010 - 10:30h

Talvez funcione com o getchar mas o que eu fiz foi limpar o buffer do teclado usando a função fflush(stdin) logo após o scanf. Com isso o scanf não pega a string armazenada no buffer. A vantagem de usar o fflush é que não preciso me preocupar com o [enter] armazenado no buffer. Depois troquei o %s por %c e rodou sem problemas!
Valeu mesmo pessoal pelas dicas!!!!!!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts