Ir ao conteúdo

C Tentativa de compilar falhando


Ir à solução Resolvido por Lucca Rodrigues,

Posts recomendados

Postado

estava criando um menu de seleção, fui testar (estou bem no comecinho mesmo) e deu esse erro:

Spoiler

/usr/bin/ld: /tmp/cc5HYbVN.o: aviso: relocalização contra "stdscr" em secção só de leitura ".text"
/usr/bin/ld: /tmp/cc5HYbVN.o: na função "main":
Palindromos.c:(.text+0x12): referência não definida para "stdscr"
/usr/bin/ld: Palindromos.c:(.text+0x1a): referência não definida para "wgetch"
/usr/bin/ld: aviso: a criar DT_TEXTREL num PIE.
collect2: error: ld returned 1 exit status

meu código:

Spoiler

#include <curses.h>

char menu = ' ';
char menuVelho = menu;

int main ()
{
        while (menu != 'X')
        {
                menu = getch();
                if (menu != ' ')
                {
                        switch (menu)
                        {
                                case 'X':
                                printf("adios :)");
                        }
                }
        }
}

 

qual o meu erro?

Postado

Você precisa linkar a biblioteca curses colocando -lcurses ou -lncurses (se um não der tenta o outro) no comando de compilação.

 

Fora isso também tem isto:

- usa printf mas não incluiu stdio.h

- a função main não retorna 0 quando é finalizada

  • Curtir 2
Postado
10 minutos atrás, isrnick disse:

Você precisa linkar a biblioteca curses colocando -lcurses ou -lncurses (se um não der tenta o outro) no comando de compilação. //funcionou (compilou*) com os dois

 

Fora isso também tem isto:

- usa printf mas não incluiu stdio.h //adicionei a linha #include <stdio.h>

- a função main não retorna 0 quando é finalizada //adicionei a linha return (0);

o projeto inicia mas fica estranho... nem quando aperto uma tecla, nem quando dou enter... a entrada/saida ficou assim:

 

Spoiler

┌──(usuario㉿pc)-[~/Programação/C/Projetos]
└─$ g++ Palindromos.c -lcurses -o Palindromos

┌──(usuario㉿pc)-[~/Programação/C/Projetos]
└─$ ./Palindromos 
q                          //entrada
x                          //entrada
X                          //entrada
^C
┌──(usuario㉿pc)-[~/Programação/C/Projetos]
└─$ g++ Palindromos.c -lncurses -o Palindromos
┌──(usuario㉿pc)-[~/Programação/C/Projetos]
└─$ ./Palindromos                                                                                                                           
q                          //entrada
x                          //entrada
X                          //entrada
^C

 

Postado

@Um mero usuário Dê uma lida nos comentários:

// Faltou incluir stdio.h
// #include <stdio.h>
#include <curses.h>

// Por que criou variaveis globais?
char menu = ' ';
// Nao usou menuVelho em lugar algum
char menuVelho = menu;

int main ()
{
    // Declare localmente na main
    // char menu = ' ';

    while (menu != 'X')
    {
        menu = getch();
        // voce nao precisa desse if...
        if (menu != ' ')
        {
            // switch com apenas um case?
            // Nao precisa disso tambem...
            switch (menu)
            {
                case 'X':
                printf("adios :)");
            }
        }
    }
    // Imprima depois do loop
    // printf("adios :)");
  
    // Faltou o return
    // return 0;
}

 

7 minutos atrás, Um mero usuário disse:

o projeto inicia mas fica estranho

E o que quer dizer por estranho? :D

getch() lê sem echo, isso sim é estranho... Imprima o caractere lido ao menos.

  • Curtir 1
Postado

fiz o seguinte projeto para testar a entrada e saída:

Spoiler


#include <curses.h>
#include <stdio.h>

char menu = ' ';
char menuVelho = menu;

int main ()
{
        while (menu != 'X')
        {
                menu = getch();
                if (menu != ' ' /*&& menu != '8'*/      /*&& menu != 8*/)
                {
                        switch (menu)
                        {
                                case 'X':
                                printf("adios :)");
                                break;
                                default:
                                printf("%c",&menu);
                                break;
                        }
                }
        }
        return (0);
}

 

já com as mudanças necessárias, adicionei um print para a entrada...

a saída é infinitamente oitos: 8888888888888888888888888888888888 (continua)...

coloquei no if aqueles oitos pra ver se elimino o problema, mas deu na mesma coisa

edit: coloquei o programa bugado pra rodar e olhei com calma a saída, achei alguns caracteres q nn eram oitos, eram teclas que eu apertei mesmo

Postado

@Um mero usuário

8 minutos atrás, Um mero usuário disse:

eu quase sempre coloco variaveis globais por organização mesmo

Isso só vai te dar problemas, variáveis globais podem ser vistas em qualquer escopo, modificadas em qualquer lugar, é um pesadelo.

 

8 minutos atrás, Um mero usuário disse:

fui testar para ver se estava certo... então postei do jeito que estava

Mas funciona 🤔

curses é uma biblioteca pra sistemas do tipo Unix, não é meu caso.

Eu apenas fiz o que te disse na outra postagem:

Em 24/05/2021 às 18:56, Lucca Rodrigues disse:

Em Windows, basta desabilitar Line Input, use SetConsoleMode().

Em Linux, desabilite Cooked Mode.

Depois disso, você pode usar fgetc(), getchar(), etc. E daí é só restaurar para o modo original.

E se quiser que seja igual a getch() mesmo, tem que desabilitar echo também.

  • Curtir 2
Postado
agora, Lucca Rodrigues disse:

@Um mero usuário

Isso só vai te dar problemas, variáveis globais podem ser vistas em qualquer escopo, modificadas em qualquer lugar, é um pesadelo.

Anotado

 

curses é uma biblioteca pra sistemas do tipo Unix, não é meu caso.

Tentei, mas não consegui, fiz uma pesquisa rápida e achei esse comando, então fui testar mesmo

 

  • Solução
Postado

@Um mero usuário

32 minutos atrás, Um mero usuário disse:

Tentei, mas não consegui, fiz uma pesquisa rápida e achei esse comando, então fui testar mesmo

Comando? Me refiro à biblioteca curses que tem a função getch().

E qual seu sistema operacional? É do tipo Unix?

Não sei programar pra esse tipo de sistema, contudo, a ideia é a mesma tanto pra Windows quanto pra Unix.

Da uma olhada nesse link, tem a implementação da getch() lá, e usa funções dessa tal termios pra alterar o modo de entrada:

#include <stdio.h>
#include <termios.h>

int getch(void)
{
    struct termios velho, novo;
    int ch;
    
    tcgetattr(0, &velho);
    
    novo = velho;
    novo.c_lflag &= ~ICANON;
    novo.c_lflag &= ~ECHO;
    
    // Alterando
    tcsetattr(0, TCSANOW, &novo);
    
    ch = getchar();
    
    // Restaurando
    tcsetattr(0, TCSANOW, &velho);
    
    return ch;
}

int main ()
{
    char menu = getch();
    
    printf("<%c>", menu);
    
    return 0;
}

 

  • Curtir 1
Postado

@Um mero usuário Para você utilizar a ncurses você precisa iniciá-la primeiro dessa maneira.

	initscr(); 		/* Inicia a ncurses */

depois de iniciada você pode escrever ou pegar algo da saída padrão com as funções.

/* Funções de saida */
	printw();		/* Funciona igual a printf() */
	addch();
	addstr();

/* Funções de entrada */
	scanw();		/* Funciona igual a scanf() */
	getch();
	getstr();

você também não precisa incluir o cabeçalho stdio.h a ncurses inclui automaticamente ele e o termios.h.

 

Quando você utilizar uma das funções de saída (como printw()) você tem que utilizar a função refresh()

	refresh();		/* Atualiza as informções do terminal */

 

Quando o seu programa terminar você tem que chamar a função endwin()

	endwin(); 		/* Finaliza a ncurses */

Ela vai restaurar todas as cagadas que você fez com o termios.h, por isso eu não recomendo a solução do @Lucca Rodrigues porque ela mexe direto com as configurações do terminal.

 

Um programa básico com ncurses é assim.

#include <ncurses.h>

int main(void)
{
	initscr(); 		/* Inicia a ncurses */

	printw("Ola mundo!\n");

	refresh(); 		/* Atualiza o terminal */

	getchar(); 		/* Espera a tecla enter */

	endwin(); 		/* Finaliza a ncurses */
	return(0);
}

 

Para compilar você utiliza a linha de comando

gcc NOME_DO_ARQUIVO.c -o NOME_DO_EXECUTAVEL -Wall -lncurses

 

para um tutorial bem mais completo e detalhado de uma olhada nesse site.

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

 

Boa sorte!

  • Obrigado 1
Postado
4 minutos atrás, kgin disse:

Ela vai restaurar todas as cagadas que você fez com o termios.h, por isso eu não recomendo a solução do @Lucca Rodrigues porque ela mexe direto com as configurações do terminal.

🤔

A segunda chamada de tcsetattr() restaura o modo original.

E não é o que endwin() faz? Restaura o terminal.

Dá no mesmo.

  • Curtir 1
Postado
5 horas atrás, Lucca Rodrigues disse:

e usa funções dessa tal termios pra alterar o modo de entrada:

 

Linux é outra coisa, e pode ser mais simples a opção: simplesmente escreva 

 

man termios

 

e tecle enter...

 

E depois leia. Muito.

 

Eis o início disso no ubuntu 20.04

 

image.png.0e5e5c70ecdd48bbae334175ada4b6d4.png

 

mas tem em todas distribuições. Se programa em C e usa Linux, considere que C foi escrita para facilitar o desenvolvimento do Unix, que foi copiado simplesmente por Mr. Torvalds que por acaso tinha um nome parecido: Linus.

 

Então tem tudo aí. tcsetattr() na tela acima por exemplo é o SetConsoleMode() do Windows quando jovem.

 

 

  • Curtir 2
  • Obrigado 1
Postado
3 horas atrás, Um mero usuário disse:

@arfneto nem sabia da existencia desse tipo de informacao no manual... vou aproveitar e ver sobre outras bibliotecas também

 

Não sei como ensinam isso hoje em dia. Mas não parece animador.

 

man é dividido em seções. A seção 3 por exemplo é a que tem as chamadas de função. A seção 5 tem os formatos de arquivo. Para ver uma lista use man man.

 

Unix precede internet e interfaces gráficas. Um volume enorme de documentação está incluído no sistema. E você, ao criar um programa, pode incluir a documentação junto e o usuário pode (e esperava) digitar man coisa e ver a documentação sobre coisa na seção pertinente.

 

Os arquivos correspondentes à documentação ficam em /usr/share em geral

 

Experimente man man para começar...

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!