Ir ao conteúdo
  • Cadastre-se

Interromper laço em C++ no Netbeans


Isabeleaa

Posts recomendados

Olá pessoal,

Estou começando no C++ e no Netbeans e estou com um problema.

Tenho um sensor numa porta USB, e meu programa liga esse sensor, fica lendo os dados dentro de um laço, e depois fecha o sensor.

Preciso mudar esse laço, pois atualmente ele limita o número de leituras do sensor (for i<100..., sendo que 100 é o número de vezes que o sensor é lido).

Tentei colocar assim:

...

#include <curses.h> //estou usando ubuntu

...

main...

do {

leSensor();

mostraDados();

} while (getch()!=27)

...

Mas apesar de ter colocado o caminho da curses.h no include do NetBeans, dá erro falando que falta o linker de duas funções que fazer parte da curses.

Tentei com getchar(), mas só lê uma vez e fica esperando a tecla Enter. Acho que se o caso acima funcionasse também iria ler uma vez só e ficar esperando uma tecla.

Alguma sugestão de como fazer para ficar lendo o sensor indefinidamente até uma determinada tecla ou comando ser digitado?

Obrigada!

Link para o comentário
Compartilhar em outros sites

Por que você não coloca um return na função leSensor()?

Declara leSensor() com um determinado tipo, int, por exemplo. Enquanto determinada condição não ocorrer, leSensor() faz aquilo que foi pensada pra fazer e retorna algo. Zero, por exemplo.

E cá fora, dentro do laço do-while, você checa o retorno: se for zero continuo, se for qualquer outra coisa, 1 por exemplo, saio do laço.


unsigned short int [COLOR="Blue"]continuar_se[/COLOR] = 0;
do
{
[COLOR="blue"]continuar_se[/COLOR] = leSensor();
mostraDados();
} while([COLOR="blue"]continuar_se == 0[/COLOR])

Você pode usar ainda uma variedade de goto, break, eventos etc.

Link para o comentário
Compartilhar em outros sites

Por que você não coloca um return na função leSensor()?

Declara leSensor() com um determinado tipo, int, por exemplo. Enquanto determinada condição não ocorrer, leSensor() faz aquilo que foi pensada pra fazer e retorna algo. Zero, por exemplo.

E cá fora, dentro do laço do-while, você checa o retorno: se for zero continuo, se for qualquer outra coisa, 1 por exemplo, saio do laço.

Então, mas o problema é estabelecer essa condição para parar a leitura. Tentei pela digitação de uma tecla (getch() da curses.h), mas dá erro "referência indefinida" para 2 funções. Tem que ter um jeito de eu avisar o programa para parar e mudar a condição.

Link para o comentário
Compartilhar em outros sites

Como é a leitura? dê um pouquinho mais de detalhes.

Você lê diretamente de comandos dados no teclado? ou de um arquivo? e se for de um arquivo, como ele ta desenhado? dados por linha? tem como prever o numero de linhas? estaria o ultimo dado na ultima linha? se sim, poderia usar o eof (end of file). Etc. Existe algum padrão que se possa usar pra identificar a ultima coisa a ser lida?

Bom, mas de qualquer maneira você não deve tentar outra solução porque não consegue linkar algo por culpa do Netbeans. A IDE não deve limitar teu projeto. Dê uma olhada na documentação dele pra ver como linkar outras bibliotecas.

Se não encontrar, pé na ***** dele. Segue o teu projeto fora do NetBeans mesmo. Onde se pode linkar tudo sem problemas.

Link para o comentário
Compartilhar em outros sites

Então, mas o problema é estabelecer essa condição para parar a leitura. Tentei pela digitação de uma tecla (getch() da curses.h), mas dá erro "referência indefinida" para 2 funções. Tem que ter um jeito de eu avisar o programa para parar e mudar a condição.

"getch() da curses.h" ?

Mas o getch faz parte da conio.h não disso aí que você falou :)

Link para o comentário
Compartilhar em outros sites

V!olador:

A leitura de de dados capturados de um sensor conectado via USB. Eu detecto esse sensor, inicio e mando ler os dados que ficam mudando continuamente. Não tem um fim, só quando eu mando encerrar o sensor, depois que acaba o laço.

A função leSensor() pega os dados daquele instante e joga numa variável para ser mostrado na tela. Tenho um controle da hora que a captura de dados é iniciada, preciso de um controle para parar na hora que o usuário da aplicação quiser.

Pensei em colocar um if dentro do laço, para testar caso ocorra uma interrupção via teclado, por exemplo.

De qualquer forma, vou testar a compilação via terminal mesmo, fora do netbeans.

Deadrools

A conio.h é do windows, estou usando linux, e a curses.h (ou ncurses,h) é a equivalente que tem a função getch().

Link para o comentário
Compartilhar em outros sites

Já que você ta usando o C++, eu iria sugerir a biblioteca Boost C++ que tem ótimas funções já prontinhas pra "event handling". Ou seja, um "gerenciador", por assim dizer, de eventos. Como quando você clica em um botão com o mouse, internamente, aquilo é um evento que deve comportar-se como descrito por um determinado pedaço de código.

Para mais detalhes (em ing): http://en.highscore.de/cpp/boost/eventhandling.html

Mas tenho a impressão que é poder demais pra algo tão simples. Parece mais fácil colocar um if mesmo dentro do laço, embora talvez você comprometa o rendimento do código.

Link para o comentário
Compartilhar em outros sites

Olá Isabele,

Antes de mais nada, gostaria de dizer que achei os seus reviews bastante simpáticos. ;) Poderia fazer vídeos.

Então, mas o problema é estabelecer essa condição para parar a leitura. Tentei pela digitação de uma tecla (getch() da curses.h), mas dá erro "referência indefinida" para 2 funções. Tem que ter um jeito de eu avisar o programa para parar e mudar a condição.

Eu não conheço muito bem NetBeans, mas deve ter alguma forma de especificar a lib da curses ao linker. Se fosse via linha de comando (estou mais habituado), você meteria: -lcurses.

Quanto ao getch(); bom, pelo o exemplo que você passou, ficou faltando inicializar o ambiente curses para que as várias rotinas possam ser utilizadas, incluindo o getch. Existem funções da curses que configuram a entrada de dados. Creio que a função cbreak() a ser chamada antes das chamadas à getch poderia permitir fazer isso que você deseja. Infelizmente não tenho como testar isso neste exato momento..

http://linux.die.net/man/3/nocbreak

Lembre-se que você deverá passar a usar as funções da curses para imprimir na tela da curses (printw, mvprintw, etc.)

Aqui no fórum, tem um colega que fez um jogo inteiro de Tetris usando a curses. Segundo ele, o código está muito bem documentado. Isso ajudaria bastante a conhecer as várias funções (e sintaxe) da curses. Tem um HOWTO (Google it) sobre a curses que poderá ser útil também.

[]'s

LNW

Link para o comentário
Compartilhar em outros sites

Consegui compilar via terminal. Não consegui achar onde trata os linker no netbeans. Mas compila, isso que importa

Coloquei a inicialização da curses e o cbreak, e mudei os pintf para printw. Porém, o programa lê e mostra apenas uma vez os dados do sensor e fica esperando digitar uma tecla, por causa do getch. Tanto faz se coloco o getch no if dentro do laço, ou na condição do while.

LNW, os reviews são antigos, mas obrigada pelo elogio! :)

Link para o comentário
Compartilhar em outros sites

Porém, o programa lê e mostra apenas uma vez os dados do sensor e fica esperando digitar uma tecla, por causa do getch.

Insira também (logo após o cbreak()):

nodelay(stdscr, TRUE);

stdscr - É a janela padrão. Se houvesse mais de uma, você a especificaria neste parâmetro (bom, não é o caso mesmo).

A ideia geral:

1) Inicializar o curses (initscr);

2) Configurar a entrada de dados (cbreak, nodelay, noecho, etc.). Naquele HOWTO você encontra o restante;

3) Laço/algoritmo ficaria mais ou menos assim:

do {

ch = getch();

Checar se ch != ERR (ou seja, uma tecla foi pressionada); Sendo, você poderia pôr o [B]ch[/B] novamente no buffer (para usá-lo na condição do seu laço) com ungetch(ch)

leSensor();
mostraDados();

} while (ch != 27);

4) Terminar o curses com endwin().

Sobre os reviews, é que achei bem completo e gostei da forma como explorou os detalhes. ;) Alguns que leio internet afora são meio que superficiais.

[]'s

LNW

Link para o comentário
Compartilhar em outros sites

Bom, aos poucos vai melhorando...

Coloquei o nodelay e não precisei mais ficar teclando algo. O laço continua sozinho. Mas está acontecendo o seguinte: estou rodando via terminal, e quando este chega na última linha o programa para sozinho, não está descendo a tela para ir mostrando como fazia antes de usar a curses. É como se a tela estivesse com tamanho fixo sem barra de rolagem ou rolagem automática.

Estou fazendo uns testes com o ch==ERR. Está funcionando, mas ignora o enter. Mandei mostrar o ch dentro do if, e o que é mostrado na tela é a tecla digitada, e não seu código ascii.

*******editado: consegui resolver isso. Estabeleci para ele para quando digitar uma letra e funcionou. Já que o ch é uma variável char, a comparação com uma letra funciona, mas com uma tecla como o "enter" não. Só que o programa para, volta na tela anterior do terminal, onde teve a chamada do programa, e não mostra de novo o texto "Escolha uma opção". Dou enter 2 ou 3 vezes até ele finalizar e voltar ao prompt.

Será que falta finalizar algo mais além do endwin()?

O código está assim:


__fpurge(stdin);
parar=1;
printf("Escolha uma opção: A - Rodar B - Encerrar \n");
tecla=getchar();

if(tecla=='A')
{
initscr();

do
{
leSensor();
mostraDados();

noecho();
cbreak();
nodelay(stdscr, TRUE);
ch=getch();
if(ch!=ERR)
if(ch=='l') //interrompe o laço quando a letra l é digitada
parar=0;


usleep(50000); // sleep 50 millisecond
} while (parar!=0);
endwin();

} // end if

O HowTo seria esse?

http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/

Link para o comentário
Compartilhar em outros sites

Porque você não coloca do printf("Escolha uma opção: A - Rodar B - Encerrar \n"); em diante dentro de um while, onde a condição pra permanecer dentro dele seria tecla != 'B'? Assim quando, eventualmente, teclas A sejam pressionadas, ele fará tudo o que deve fazer se tecla == 'A' e voltará a pedir outra vez. Por sinal, pro código ficar mais limpo, toda a execução da opção tecla == 'A' poderia ser colocada dentro de uma função, assim você já condensa umas 10 linhas.

Link para o comentário
Compartilhar em outros sites

Na verdade já está dentro de um while, é que eu copiei só a parte de dentro do while pra publicar aqui. E justamente porque esse trecho eu vou colocar numa função, assim que estiver funcionando redondinho.

A inicialização e fechamento do sensor eu já coloquei em função, fora do main, pra organizar.

E essa parte das opções A e B é uma "porquice" que eu fiz no código só pra testar mesmo.:P

Link para o comentário
Compartilhar em outros sites

Ave Isabele, tudo bom? ;)

Desculpe a demora, ando um pouco atribulado...

Na verdade já está dentro de um while, é que eu copiei só a parte de dentro do while pra publicar aqui. E justamente porque esse trecho eu vou colocar numa função, assim que estiver funcionando redondinho.

A inicialização e fechamento do sensor eu já coloquei em função, fora do main, pra organizar.

E essa parte das opções A e B é uma "porquice" que eu fiz no código só pra testar mesmo.:P

Isabele, eu montei um pequeno exemplo funcional e creio que você poderá adaptar às suas necessidades. A questão de não rolar a tela, é que você precisa ligar a rolagem de tela (vide função abaixo).

#include <curses.h>
#include <unistd.h>

int main()
{

char tecla, ch;
char wait[] = {'/','-','\\','|'};
int i = 0;

initscr();

do
{
clear();
nodelay(stdscr, FALSE);
echo();
nocbreak();
printw("Escolha uma opcao: A - Rodar / B - Encerrar\n");
tecla = getch();

if (tecla == 'A')
{
clear();
noecho();
cbreak();
scrollok(stdscr, TRUE);
nodelay(stdscr, TRUE);

do
{
ch = getch();

if (ch != ERR)
{
ungetch(ch);
ch = getch();
}
else
{
//leSensor();
//mostraDados();
mvprintw(10,10, "Rotinas em andamento... %c", wait[(i++)%4]);
mvprintw(12,10, "ESC para encerrar . . .\n");
refresh();
usleep(50000);
}

}
while (ch != 27);

}

}
while (tecla != 'B');

endwin();
return 0;
}

Um abraço,

LNW

Link para o comentário
Compartilhar em outros sites

Também estou demorando pra responder, pois estou trabalhando em dois projetos ao mesmo tempo.

Faltava o scrollok(stdscr, TRUE) e o ungetch(ch).

Agora funcionou redondinho! :D

Vou dar uma estudada naquele howto, a curses tem muitos recursos e ainda vou ter que usar ela mais um pouco (agora pra ler as portas usb onde estão os sensores, informação esta digitada pelo usuário).

Muito obrigada pela ajuda!!

Link para o comentário
Compartilhar em outros sites

Isabele,

Também estou demorando pra responder, pois estou trabalhando em dois projetos ao mesmo tempo.

Umm, legal.. ;)

Faltava o scrollok(stdscr, TRUE) e o ungetch(ch).

Agora funcionou redondinho! :D

Aquele trecho que tem o ungetch() nem seria necessário no seu caso; poderia retirar esta parte:

if (ch != ERR)
{
ungetch(ch);
ch = getch();
}

e colocar aquelas instruções da parte do else dentro deste teste apenas:

if (ch == ERR) {


}

Esse teste é importante para não haver atraso para sair ao pressionar o ESC.

Happy coding! ;)

[]'s

LNW

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...