Problema com lixo de memória(fflush)

Alguém poderia me informar porque mesmo antes de eu inserir valores nas minhas variáveis string, elas já vem com lixo de memória e mesmo usando fflush o lixo não limpa;

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

main(){
	
	char sexo[10], corOlhos[10], corCabelos[10];
	int idade, somaIdade, cont=0, cont2=0, cont3=0;
	float mediaIdade, porc1, porc2;
	
	printf("Sexo: ");
	scanf("%s", &sexo);
	fflush(stdin);
		
	printf("Cor do olhos: ");
	scanf("%s", &corOlhos);
	fflush(stdin);
			
	printf("Cor do cabelo: ");
	scanf("%s", &corCabelos);
	fflush(stdin);
		
	printf("Idade: ");
	scanf("%d", &idade);
	
	while(idade!=-1){
			
		printf("\n");
		
		somaIdade = somaIdade + idade;
		
		cont++;
					
		if(strcmp(sexo, "feminino") == 0 && idade > 18 && idade < 35 && strcmp(corOlhos, "verde") == 0 && strcmp(corCabelos , "louro") == 0){	
			cont2++;	
		}
		
		if(strcmp(sexo, "masculino") == 0 && strcmp(corOlhos, "verde") == 0 && strcmp(corCabelos , "preto") ==0 ){
			cont3++;
		}
		
		printf("Sexo: ");
		scanf("%s", &sexo);
		fflush(stdin);
		
		printf("Cor do olhos: ");
		scanf("%s", &corOlhos);
		fflush(stdin);
			
		printf("Cor do cabelo: ");
		scanf("%s", &corCabelos);
		fflush(stdin);
		
		printf("Idade: ");
		scanf("%d", &idade);
					
	}
		
		mediaIdade = somaIdade/cont;
		porc1 = 100 * cont2/cont;
		porc2 = 100 * cont3/cont;
		
		printf("Media de idade: %.2f\n", mediaIdade);
		printf("Porcentagem de indivíduos do sexo feminino cuja idade está entre 18 e 35 anos (inclusive) e que tenham olhos verdes e cabelos louros: %.2f\n", porc1);
		printf("Porcentagem de indivíduos do sexo masculino cujos olhos são verdes e os cabelos são pretos: %.2f\n", porc2);
		

	
	
}

http://www.cprogressivo.net/2012/12/Buffer--o-que-e-como-limpar-e-as-funcoes-fflush-e-fpurge.html

http://blog.alura.com.br/limpando-lixo-da-memoria-em-c/

http://pt.stackoverflow.com/questions/9427/limpeza-do-buffer-do-teclado-após-scanf

Por que é assim que a linguagem funciona. Se você quer limpar, simplesmente atribua um valor para elas:

char sexo[10] = ""; char corOlhos[10] = "";

Outra coisa. Para ler strings com o scanf não use o &. O char[] já é encarado pela linguagem como uma espécie de ponteiro.

2 curtidas

Olá tobiasan!

O seu problema é muito simples e fácil de resolver.

Primeiro de tudo, é importante lembrar que um vetor é uma coleção de variáveis que são alocadas sequencialmente na memória. Tá, e daí?

Veja,

sexo[0], sexo[1], sexo[2], …, sexo[10].

Quando vamos “utilizar” o vetor para algo, usamos sua referência e não o seu valor. Ou seja, quando dizemos sexo[3], estamos acessando o endereço da memória onde o indice 3 do vetor sexo está.

Outro ponto interessante é entender que o ‘&var’ é um operador também. Quando usamos antes de uma variável, estamos dizendo para o sistema alocar um valor (no caso do scanf()) no endereço de memória da variável var. Lembra que o vetor é um conjunto de variáveis e que estas estão alocadas sequencialmente na memória? Logo, você não precisa acessar um elemento específico do vetor para preenchê-lo, você precisa apenas dizer para o sistema onde o vetor começa. Resumindo:

ao invés de usar:

use

scanf("%s", sexo);

que ele vai dizer pro sistema: “Aloque o que o cara está digitando, mas parta do primeiro elemento do vetor sexo, ok?”.

Com isso você não precisará do famos fflush :slight_smile:. O código ficará mais ou menos assim:

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

int main(void){

	char sexo[10], corOlhos[10], corCabelos[10];
	int idade, somaIdade, cont=0, cont2=0, cont3=0;
	float mediaIdade, porc1, porc2;

	printf("Sexo: ");
	scanf("%s", sexo);

	printf("Cor do olhos: ");
	scanf("%s", corOlhos);

	printf("Cor do cabelo: ");
	scanf("%s", corCabelos);

	printf("Idade: ");
	scanf("%*c%d", &idade);

	while(idade!=-1){

		printf("\n");

		somaIdade = somaIdade + idade;

		cont++;

		if(strcmp(sexo, "feminino") == 0 && idade > 18 && idade < 35 && strcmp(corOlhos, "verde") == 0 && strcmp(corCabelos , "louro") == 0){
			cont2++;
		}

		if(strcmp(sexo, "masculino") == 0 && strcmp(corOlhos, "verde") == 0 && strcmp(corCabelos , "preto") ==0 ){
			cont3++;
		}

		printf("Sexo: ");
		scanf("%s", sexo);


		printf("Cor do olhos: ");
		scanf("%s", corOlhos);

		printf("Cor do cabelo: ");
		scanf("%s", corCabelos);

		printf("Idade: ");
		scanf("%d", &idade);

	}

		mediaIdade = somaIdade/cont;
		porc1 = 100 * cont2/cont;
		porc2 = 100 * cont3/cont;

		printf("Media de idade: %.2f\n", mediaIdade);
		printf("Porcentagem de indivíduos do sexo feminino cuja idade está entre 18 e 35 anos (inclusive) e que tenham olhos verdes e cabelos louros: %.2f\n", porc1);
		printf("Porcentagem de indivíduos do sexo masculino cujos olhos são verdes e os cabelos são pretos: %.2f\n", porc2);



return 0;
}

Acredito que seja muito agregador esta discussão: https://www.scriptbrasil.com.br/forum/topic/184666-código-para-de-funcionar/#comment-692161

Ela informa o quão desnecessária o fflush pode ser e o quão simples pode ser substituíla.

1 curtida

Vlw. Consegui corrigir.

Obrigado pela explicação. Bem didática!

1 curtida

Srs, bom dia, sei que o post é antigo, porem não muda muita coisa em c++, a duvida de hoje pode ser respondida por conteúdo de 10, 15 anos, vamos lá !

Fiz uma calculadora, mas estou com dúvida na limitação de caracteres em OP, quero limitar em apenas 1 caracter, porem não consigo em OP[1] , tentei o comando sugestionado acima para limpar, o que me parece que ao digitar qualquer dado em OP, o aplicativo entende que são caracteres isolados, e replica a pergunta pela quantidade de caracter, vou postar o código completo, gentileza ajudar.

Tentei o fflush em vários locais e não consegui, segue o código.
#include
#include
#include <unistd.h>
using namespace std;
int main() {
char op; // here the problem
double num1, num2, result;
remake:

cout << “Enter the operator + - * / :”;
cin >> op;
if (op == ‘+’ || op== ‘-’ || op== ‘*’ || op== ‘/’) {goto calculo;}
else { goto remake; fflush(stdin) ;}

calculo:
cout << "Enter two numbers one by one ";
cin >> num1 >> num2;
operation:
switch (op) {
case ‘+’:
cout << num1 << " + " << num2 << " = " << " + Answer addition = " << num1 + num2;
break;
case ‘-’:
cout << num1 << " - " << num2 << " = " << " - Answer subtration = " << num1 - num2;
break;
case '':
cout << num1 << " x " << num2 << " = " << "
Answer multiplication = " << num1 * num2;
break;
case ‘/’:
if (num2==0) { cout<< “number invalid to division”;}
else{ result = num1/num2;
cout << num1 << " / " << num2 << " = " << “/ Answer division =”<< result; }

break;

erro:
cout<< “Operador invalid” << “\n”;
goto remake;
}
return 0;
}

Onde vc que aprendeu que se deve usar goto? Me impressiona se alguém ensina esse tipo de coisa que é totalmente desencorajada desde a década de 1970. Há construções de nível mais alto que excluem TOTALMENTE a necessidade de tal prática. Um ponto de partida para te convencer c++ - What is wrong with using goto? - Stack Overflow

Seu problema é que o pulo de linha da entrada que fica no buffer. Quando seu cin >> op; executa, o caractere de pulo de linha não é consumido, então no primeiro cin que aparecer depois vai consumir esse pulo de linha para encontrar algo na entrada. O fflush não tem um comportamento padrão garantido. Como esse é um mero programa de brinquedo, basta usar um getchar() depois do cin do operador para descartar o pulo de linha. Seu código, atualizado, sem gotose com o inglês ajustado, poderia ser algo como:

#include <iostream>

using namespace std;

int main() {

    char op;
    double num1;
    double num2;

    while ( true ) {

        cout << "Provide the operator + - * / : ";
        cin >> op;
        getchar();

        if ( op == '+' || op == '-' || op == '*' || op == '/' ) {

            cout << "Provide two numbers one by one: ";
            cin >> num1 >> num2;

            switch ( op ) {

                case '+':
                    cout << num1 << " + " << num2 << " = " << num1 + num2;
                    break;

                case '-':
                    cout << num1 << " - " << num2 << " = " << num1 - num2;
                    break;

                case '*':
                    cout << num1 << " * " << num2 << " = " << num1 * num2;
                    break;

                case '/':

                    do {
                        if ( num2 == 0 ) {
                            cout << "The second number can't be zero!" << endl;
                            cout << "Provide the second number again: ";
                            cin >> num2;
                        }
                    } while ( num2 == 0 );

                    cout << num1 << " / " << num2 << " = " <<  num1 / num2;
                    break;

            }

            break;

        } else {
            cout << "Invalid operator!" << endl;
        }

    }

    return 0;

}

Por isso que existem Professor e aluno…estou na fase de aluno ainda kkk

o código funciona, porem quando se digita dois caracteres, ele dá duas sequencias de respostas, se digita 5 digitos, ele repete a mesma mensagem 5x, fora disso tudo ok.

1 curtida