Problemas com ncurses e getch (resolvido)

Iniciado por jth., 16 de Novembro de 2008, 16:43

tópico anterior - próximo tópico

jth.

Olá, eu sou um novato no mundo GNU/Linux, instalei o Ubuntu 8.1 a poucos dias (creio que 4 dias).
Inicialmente senti dificuldade pelas diferenças com o Ruindows, mas estou superando elas pouco a pouco, a instalação de novos programas foi uma dificuldade até entender o funcionamento do Adicionar/Remover, o tal apt-get.

A maioria dos problemas que eu tive consegui solucionar sozinho com a ajuda de rápidas buscas em alguns tópicos do fórum, mas realmente estou empacado em um pequeno problema.

Eu sou estudante de Engenharia de Computação, primeiro semestre, e comecei a ser instruído na programação em C a pouco, até agora usava o DevC++, no Ruindows. Assim que comecei a mexer com o linux uma das minhas preocupações seria como faria para programar em C no linux, usando o adiconar/remover achei o Anjuta, mas não gostei muito dele. Comecei a testar como seria compilar através do tal "GCC" usando apenas o gedit, inicialmente correu tudo bem, até começar a testar programas usando a conio.h e a função getch (que uso para pausar os "programas").

Mais uma vez com uma rápida busca no fórum entendi que a conio.h não é uma biblioteca (é esse o termo?) nativa do linux, mas que existia a ncurses.h/curses.h que resolveria meu problema com o "getch". Instalei a ncurses usando um comando do apt-get que peguei em algum dos tópicos que estava lendo, a instalação pareceu OK, mas o problema não foi totalmente sanado.

Realmente o GCC está compilando os programas que uso o getch, mas eles não funcionam, aparentemente a função getch está sendo totalmente ignorada. Eu não sei onde estou errando, talvez a sintaxe da linha de comando? O é necessário algo alem disso para rodar curses.h?

Eis um exemplo simples:
Citar#include <curses.h>

#include <stdio.h>



main() {

   float x;

   printf("\n\tDigite um numero.");

   x = getch();

   printf("\n\tVoce digitou %.2f\n",x);

   getch();

}



Como podem ver ele não pausou para eu digitar nada, seguiu adiante e considerou a variável "x" como -1.00.

o.O

Outra coisa, eu tinha lido que a função getchar(); também pode servir para pausar um programa, tentei voltar no tópico que tinha lido mas não achei novamente, qual a biblioteca que essa função usa? Curses.h? E posso usar ela no lugar do getch mesmo? Li algo sobre buffer ou algo assim, mas não entendi realmente.

Espero que possam me ajudar, o problema é simples e o texto é um pouco grande, mas eu acredito que as coisas "em seus mínimosssss detalhes" são úteis na hora de tirar dúvidas.


Até mais ;D


--------------------------------------|| EDITADO (20:00) ||--------------------------------------

Ah! Pesquisei na net sobre a ncurses e consegui entender o problema. Aparentemente para usar as funções da ncurses você tem que chamar a biblioteca e fechá-la depois de usar através dos comandos:
initscr(); /* para chamar ncurses */
endwin(); /* para fechar */

Bom, não sei se na conio.h existem comandos semelhantes, mas nunca precisei utilizar nada parecido para usar o getch();

O programa teste ficou assim:
Citar#include <curses.h>
#include <stdio.h>

main() {
   char x;
   initscr();
   printw("\n\tAperte uma tecla.");
   noecho(); /* serve para nao mostrar a tecla apertada */
   x = getch();
   printw("\n\tVoce digitou %c\n",x);
   getch();
   endwin();
}

Só não entendi pq tive que definir a variável como "char". Quando eu definia como int e digitava um número ele voltava outro número "48+x", alguém sabe explicar pq isso acontece?

Em um dos tutoriais que eu li (esse) ele fala da função "keypad(stdscr, TRUE)", segundo ele serve para "carregar o módulo do teclado para a tela padrão", como assim?? Se é o caso eu só poderia usar o getch depois de executar essa função, não?


Até mais o/

edsonsguizzato

Meu problema é basicamente o mesmo. Com o agravante que as funções initscr() e endwin() retornam respectivamente: undefined reference to `initscr' e undefined reference to `endwin'.
Estou utilizando a IDE Geany para programar.
http://umbyte.com
Informações em 8 bits
Ubuntu User # 22757

jth.

#2
Citação de: edsonsguizzato online 17 de Novembro de 2008, 16:34
Meu problema é basicamente o mesmo. Com o agravante que as funções initscr() e endwin() retornam respectivamente: undefined reference to `initscr' e undefined reference to `endwin'.
Estou utilizando a IDE Geany para programar.

É mesmo, não baixei o Geany, mas baixei o Code::Blocks e dá a mesma mensagem quando tento compilar usando essas funções. Para "puxar" a ncurses usando o GCC basta adicionar o parâmetro "-lncurses", mas e para usar nessas IDE's? Alguém ae se habilita a explicar?

Até mais ;P



================// EDITADO(22:26) \\================
Cara, fuçando aqui no Code::Blocks eu consegui "fazer funcionar", não sei se fiz o certo, mas funcionou.
Eu fui em Settings >> Compiler and debbuger
aí fui em Linker Settings e em "Link libraries" cliquei em "add" e digitei "ncurses"... pronto... passou a funcionar, vou baixar o Geany, se eu ver algo parecido posto aqui.

Até mais ;D



================// EDITADO(22:51) \\================
Mexendo aqui eu achei...
Indo em Construir >> Definir Includes e Argumentos
Você troca (na caixinha do "Construir")
Citargcc -Wall -o "%e" "%f"
Por
Citargcc -Wall -o "%e" "%f" -lncurses
Bom... se seu problema era o mesmo que o meu isso deve resolver, agora é só compilar... Se não funcionar então... o seu problema não era o mesmo que o meu ;D. Boa sorte o/

Até...

Darcamo

Quando você inclui uma biblioteca no seu programa o compilador, no caso o GCC, precisa saber onde estão os arquivos de cabeçalho dessa biblioteca e o linkador precisa saber onde está a biblioteca compilada (para linkar junto com o executável do seu programa).

Para incluir um diretório onde se encontra o ".h" você passa a opção "-L" + diretório para o GCC. Algo como
gcc meuprograma.c -L/pathCompletoDoDiretório

Só que bibliotecas padrões no linux ficam em lugares específicos e o GCC pode achar os arquivos ".h" sem que você precise especificar o diretório.
Esperimenta ver a pasta /usr/include e verá vários arquivos ".h ".


Já com respeito a biblioteca compilada, você precisa dizer com que bibliotecas deseja linkar o seu programa usando a opção "-l" (L minúsculo) + nome da biblioteca.
Ficaria então assim
gcc meuprograma.c -lBibliotecaLegal
Bom, as bibliotecas também ficam em uma pasta padão (/usr/lib), mas o linkador não pode linkar com todas ou testar com qual delas ele deveria linkar. Logo, você deve especificar explicitamente, que no caso seria com
gcc seuprograma.c -lncurses

No caso das IDEs, você adiciona a biblioteca em algo como "Linker Settings" (como você descobriu), "External Libraries", ou algo semelhante.
Como essa configuração da IDE é justamente para adicionar bibliotecas para serem linkadas, normalmente você não precisa adicionar o "-l" já que a IDE adiciona para você. Logo, você escreve apenas o nome da biblioteca como você fez.


Com relação ao erro "undefined reference", note que ele ocorre justamente na hora da linkagem. Ou seja, o GCC achou o .h da biblioteca, compilou o seu programa, mas na hora de linkar com a biblioteca que contém aquela função legal que você usou o linkador não achou a biblioteca contendo a definição da função e a função ficou indefinida (declarada no .h, mas não implementada já que não linkou com a biblioteca).

jth.

#4
Valeu pelas explicações Darcamo, agora ficou tudo bem mais claro.  ;D
Vou colocar como resolvido...

Até mais o/

Darcamo

Se estiver interessando, tem um tópico que criei antigo falando o básico de como criar um Makefile
http://ubuntuforum-br.org/index.php/topic,21155.0.html

As IDEs costumam criar um makefile para você, mas saber um pouco é útil.