Posts Tagged 'c'

C++: Programação correta

Muitas coisas incorretas são ensinadas aos estudantes de programação. Por exemplo:

system(“pause”);

Que para a tela em um certo ponto. O problema é que o comando system( ) envia algum comando ao prompt do sistema. O que, obviamente só vai funcionar em um SO. Um jeito melhor de fazer isso seria:

while(getchar() != ‘\n’);

Que tem o mesmo efeito, mas funciona em qualquer SO. Outro problema é:

fflush(stdin);

Ao ler uma string com gets ou fgets, se um scanf for dado antes, o ‘\n’ do ENTER utilizado para inserir um valor no scanf será pego pelo fgets/gets. O fflush limpa o buffer certo? Não. fflush é utilizado para buffers de saída, de forma que seu uso em buffers de entrada gera um comportamento imprevisível. Além, disso, não funciona fora do Windows. No Linux, você poderia usar:

__fpurge(stdin);

Que é a mesmo coisa (errada) e só funciona em Linux. O que fazer então? A questão é que você precisa “capturar” o  caractere ‘\n’ fujão do scanf( ). Você pode fazer isso com um:

scanf(“%i%*c “, &variavel);   (o scanf lê o inteiro que queremos e depois lê um caracter que, devido ao asterisco, será jogado fora. Esse é o ENTER)

Ou:

scanf(“%i”, &variavel)

getchar( );   (pega o ENTER que escapou acima)

Mas suponhamos que o usuário mala, ao (por exemplo) digitar um inteiro no scanf( ), deu uns 20 espaços e apertou o enter. O getchar( ) irá pegar um espaço e deixará todos os outros e mais o ENTER rodando por aí. O scanf( ) com asterisco fará a mesma coisa. Solução? Lembra do pause que eu criei acima? Ele basicamente pega qualquer caracter até achat um ‘\n’ (ENTER)! Então:

scanf(“%i”, &variável);

while(getchar() != ‘\n’);

fgets(….)

Com isso o buffer será limpo e o fgets irá funcionar. Você pode criar um procedimento para não ter que ficar digitando isso o tempo todo. Esse procedimento serve para dar pause e limpar o buffer (esse é bom!!!):

void pause( ){

while(getchar( ) != ‘\n’);

}

Lembra que eu falei sobre a dupla:

gets(variavel);

E:

fgets(variavel, 40, stdin);

onde:

variável: aonde você vai salvar a string.

40: valor de exemplo. Pode ser qualquer inteiro. Corresponde ao tamanho da variável aonde você vai    guardar a string lida.

stdin: local de onde a string será lida (stdin é a entrada padrão, o teclado). Poderia ser um arquivo, stream, etc.

O que as duas fazem? Ora, leem uma string. Se ambas fazem a mesma coisa, porque usar a segunda, que é mais complicada? Simples. Suponhamos que sua string tenha 20 caracteres. Na hora de ler, o usuário digitou 50 caracteres e deu ENTER. O gets vai pegar 20 caracteres, colocar na variável, e irá deixar os outros 30 no buffer, jogando dados aleatórios no seu programa todo. Que encrenca… O fgets pega as 20 e, como sabe que esse é o tamanho da string, apenas joga o resto fora, sem jogar os dados no resto do seu programa. Se você compilar o código no GCC, verá que ele nem aceita o gets (uma das maiores vantagens do GCC na minha opinião é que ele não aceita POG).

Espero que tenham apreciado essas dicas. A melhor forma de aprender a programar é aprender certo desde o começo. Isso gera código de qualidade e evita problemas.

Anúncios

Code::Blocks – IDE para C/C++

Como o título diz, Code::Blocks é uma IDE multiplataforma para C/C++. Adotei o Code::Blocks como meu ambiente de programação para C (também serve para D e Fortran) devido aos seus recursos e sua solidez. A IDE é muito leve, iniciando em poucos segundos. Ela detecta automaticamente os compiladores instalados e, na primeira execução, pergunta qual deverá ser o default (no meu caso, o GCC). O programa tem um excelente modo de debug, com código em assembler, informações sobre memória e CPU, acompanhamento de variáveis e muito mais. Um dos destaques é o fato que o Code::Blocks possui um designer de interfaces para C++ usando wxWidgets, o que gera programa multiplataforma. É possível configurar o compilador e suas flags. Com certeza, o melhor ambiente para C/C++ que já usei. Pode testar.

Obs.: instale os pacotes codeblocks e codeblocks-contrib, que tem plugins extras.