GCC

te-x

Power Member
Estou a usar o Ubuntu e já tenho o GCC instalado. Estava a aprender a programar C em windows, com o Dev C++, mas agora que já tenho o Linux não quero estar a ir para o Windows sempre que quero programar...

Estou a escrever o código no Gedit, mas depois não consigo compilar. No terminal/consola faço gcc -Wall -O2 hello.c mas depois tenho estes erros:
hello.c:1:19: error: stdio.h: Ficheiro ou directoria inexistente
hello.c:2:20: error: stdlib.h: Ficheiro ou directoria inexistente
hello.c: In function ‘main’:
hello.c:6: warning: implicit declaration of function ‘printf’
hello.c:6: warning: incompatible implicit declaration of built-in function ‘printf’
hello.c:8: warning: implicit declaration of function ‘system’

Deve ser por ainda não ter instalado as Bibliotecas mas não sei como e que as instalo. Alguém me consegue fazer um mini-tutorial ou dar-me um site que me explique isto?

Se algum destes erros for de código mal escrito fica aqui o código:
#include <stdio.h>
#include <stdlib.h>

int main()
{
printf("Hello World!");

system("PAUSE");
return 0;
}
 
Código:
system("PAUSE");

Isto em Linux não funciona. Isto não é código C, mas sim um comando interno do Windows.

Aparte isto, és capaz de ter de instalar as bibliotecas, mas eu não sei trabalhar com Linux, nessa área não posso ajudar.
 
basta escrever isto num terminal para instalar as libraries :

Código:
sudo apt-get install build-essential
depois já vais conseguir compilar :)
 
Estou a usar o Ubuntu e já tenho o GCC instalado. Estava a aprender a programar C em windows, com o Dev C++, mas agora que já tenho o Linux não quero estar a ir para o Windows sempre que quero programar...

Estou a escrever o código no Gedit, mas depois não consigo compilar. No terminal/consola faço gcc -Wall -O2 hello.c mas depois tenho estes erros:


Deve ser por ainda não ter instalado as Bibliotecas mas não sei como e que as instalo. Alguém me consegue fazer um mini-tutorial ou dar-me um site que me explique isto?

Se algum destes erros for de código mal escrito fica aqui o código:

E substitui também o system("PAUSE"); por getch(); para "parar" o prompt.
 
Cuidado...

getch() é uma função da biblioteca conio.h, que não se encontra disponível em Linux, tanto quanto sei. O mais apropriado para fazer um "Pressione [Enter] para continuar" aqui é a função getchar().
 
Mas a ideia do system("PAUSE"); neste caso não é para se conseguir ver o "hello world" ao executar directamente no devc++?é que em linux como tem que ser feito directamente no terminal já não há essa necessidade...penso eu..
Mas se for mesmo para parar é o getchar sim senhor!
 
Vamos lá ver se eu consigo explicar isto bem:

Como já foi dito, a instrução system("pause") só funciona em Windows. Porquê? Porque a função system equivale a chamarmos o comando passado como argumento num terminal. Em Windows, esse terminal é nada mais nada menos que a linha de comandos do MS-DOS. Experimentem abri-la, escrevam pause e pressionem Enter. Verão que tem o mesmo efeito.

Em sistemas Linux, também é legítimo fazer system("pause"), mas não terá o mesmo efeito, a não ser que tivéssemos um ficheiro binário chamado "pause" naquelas pastas onde estão os ficheiros binários que costumamos usar em terminais Linux (sudo, ls, entre outros), que fizesse o mesmo efeito que o "pause" do Windows. Assumindo que esta última situação não ocorre, o mais provável é que o terminal onde estamos a executar o programa dê um erro a dizer algo do género "pause não foi encontrado".

Resumindo e concluindo, o system("pause") só se aplica à maioria dos utilizadores de Windows, que não querem que a consola do programa feche quando este terminar, e que não gostam das complicações que o getchar() traz. No exemplo do "Hello World", o getchar() funciona às mil maravilhas, mas depois há muita gente que é ensinada a utilizar funções como o scanf, que deixam \n's, \r's, \t's e afins no standard input. E aí é que as coisas correm mal, porque metem lá o getchar() e o getchar() não causa a "paragem" do programa porque ainda existem caracteres no standard input.

Espero que todos tenham compreendido. Cumprimentos.
 
já está a funcionar, com o comando " gcc -Wall -I/usr/include -o hello hello.c[/b] " criou-me o ficheiro hello.exe (se um executável de linux for igual ao executável de windows), mas agora não consigo correr aquele ficheiro. É preciso mais alguma coisa?

Mr_Miguel, obrigado pelo explicação só não percebi qual é o problema do getchar :S
 
Se estiveres em Windows, experimenta correr isto:

Código:
#include <stdio.h>

int main() {
  int o_meu_inteiro = 0;
  printf("Introduz um inteiro: ");
  scanf("%d", &o_meu_inteiro);
  int dobro_do_inteiro = o_meu_inteiro * 2;
  printf("O dobro do inteiro introduzido e %d\n", dobro_do_inteiro);
  getchar();
  return 0;
}

Neste exemplo, o getchar() não "bloqueia" a aplicação. Porquê? Porque quando introduzes um inteiro e carregas em [Enter], o standard input fica com esse inteiro seguido de um caracter '\n'. Por exemplo, se introduzires 32 e carregares em [Enter], o standard input (que é visto como um buffer em C) fica com {'3', '2', '\n'}. Ora o scanf lê os caracteres numéricos, mas deixa o '\n' no standard input. Acontece que o getchar() só "bloqueia" se não houver caracteres disponíveis no standard input. Mas há! Ainda há o '\n'! Por isso é que, se mandares o Dev-C++ correr isto, a janela desaparece de imediato.

Conclusão: se estiveres em Windows, não te chateies com isto até seres mais avançado e usa o system("pause"). Em Linux, não existe qualquer necessidade do system("pause"). Quando estiveres mais avançado, é possível que queiras um método para "pressionar [Enter] para continuar", e é nessa altura que o que eu digo nestes posts se torna útil. Mas para já os posts eram mais a título de esclarecimento ao good_in_bed e eram um aviso amigável para ti no sentido de não usares a função getch(), ao contrário do que o MadOnion sugeriu (que é completamente diferente da getchar()).
 
Mas para já os posts eram mais a título de esclarecimento ao good_in_bed e eram um aviso amigável para ti no sentido de não usares a função getch(), ao contrário do que o MadOnion sugeriu (que é completamente diferente da getchar()).

Ainda bem que corrigiram, eu até nem uso o getCh()(nem sei porque recomendei em detrimento do getChar()), e claro só programo C em linux, mas ultimamente só tem sido Java, daí algumas já estarem a cair no esquecimento.
 
...criou-me o ficheiro hello.exe (se um executável de linux for igual ao executável de windows), mas agora não consigo correr aquele ficheiro. É preciso mais alguma coisa?

Por defeito, os executáveis em Linux não têm extensão (i.e. não têm .exe no fim). Se o teu commando continha "-o hello" então o executável chama-se simplesmente "hello". Para o correres, fazes "./hello" (sem aspas) no terminal, desde que antes disso faças uns "cd" para navegares no terminal até ao directório onde ele está. Era essa a tua dúvida? Ou não consegues correr o executável por outra razão?
 
Bem..Já que o Mr_Miguel teve a amabilidade de esclarecer-me duvidas que eu não tinha, pode agora esclarecer as que eu tenho...
Como contornar esse problema do getchar()?(Ou do gets que acontece a mesma coisa...)
 
Normalmente faz-se um fflush(stdin); para limpar o buffer de entrada, e aí o getchar já actua como esperamos. O único problema é o fflush() não ter o efeito em ficheiros de entrada documentado. Normalmente limpa o buffer de entrada (tal como faz ao de saída -> aquilo para que foi feito) mas nada nos garante que de uma versão do compilador para outra não deixe de o fazer: simplesmente não está definido o seu comportamento nesta situação.

Até agora não encontrei nenhum compilador (quer em windows quer em linux) em que o fflush(stdin); não funcione, mas fica o aviso.
 
comigo o fflush(stdin); nunca funcionou, programo em linux e mac.
a função cujo objectivo é "descartar" dados existente num buffer é o fpurge, no entanto esta função não é standard, e, como tal, pode não existir em alguns SOs (acaba por ter o mesmo problema que o fflush, uma pode não funcionar, outra pode não existir :)).
 
O problema do fflush(stdin) é mesmo esse: tem comportamento indefinido para o stdin, por isso nunca devem fazer isso. Para responder à dúvida que efectivamente tens (peço desculpa, já agora, se te ofendi ao ter esclarecido uma dúvida que não tinhas; a minha intenção não era essa), temos duas soluções:

1) Utilizar a função fgets(). Problema: o fgets recebe um inteiro, que determina o número máximo de caracteres a ler. E se o utilizador introduzir mais do que esse número? Aí, quando chamamos o getchar(), não bloqueia à mesma, porque faltam caracteres por ler. Só funciona, portanto, desde que o utilizador introduza um número "razoável" de caracteres, o que nunca podemos garantir.

2) Criar uma função para ler uma string do utilizador com um número indefinido de caracteres. Sim, é possível. Eu próprio criei uma. Cá vai o código:

Código:
char* readString(int expected_size) {
  int size = expected_size;
  char* mystring = (char*)malloc(size*sizeof(char));
  if (mystring == NULL) {
    return NULL;
  }
  int i = 0;
  for (i = 0; ;++i) {
    if (i == size) {
      char* old_pointer = mystring;
      mystring = (char*)realloc(mystring, 2*size*sizeof(char));
      free(old_pointer);
      if (mystring == NULL) {
        return NULL;
      }
      size *= 2;
    }
    int my_character = getchar();
    if (my_character == '\n') {
      mystring[i] = '\0';
      break;
    }
    mystring[i] = (char)my_character;
  }
  return mystring;
}

Este código baseia-se no que acontece com vectores noutras linguagens: se o limite que impomos na string for ultrapassado, é redimensionada para o dobro. Notem que o '\n' é lido, mas nunca é colocado na string. Podemos aperfeiçoar a função colocando tambem lá outros caracteres como '\r', '\t', etc., mas deixo isso ao vosso critério.
 
Pois, com o fflush(stdin) também nunca funcionou comigo...
Eu nestes casos costumo em vez de utilizar um gets,uso dois, fazendo um deles esse papel de limpeza. So acho um pouco...deselegante.Ou terá mais problemas?
O gets no fundo não terá o funcionamento dessa tal função de numero indefinido de caracteres?

Mr_Miguel, não fiquei ofendido ;) Eu no meu primeiro post apenas tentei responder aquilo que pensei ser a verdadeira duvida do te-x, e não estar explicar coisas alem daquilo que ele realmente precisaria...
 
O gets no fundo não terá o funcionamento dessa tal função de numero indefinido de caracteres?

Não. O gets() não redimensiona a string, como a função que eu postei. Por isso, imagina que crias uma string de 32 caracteres, mas introduzes 33. Dá asneira, obviamente.

Eu no meu primeiro post apenas tentei responder aquilo que pensei ser a verdadeira duvida do te-x, e não estar explicar coisas alem daquilo que ele realmente precisaria...

Confesso que os meus posts não tinham propriamente a finalidade de ajudar o te-x. Surgiram foi devido ao facto de o MadOnion ter sugerido a função getch() em vez da getchar(), que mais tarde se veio a descobrir que foi um pequeno engano da parte dele. De certa forma, isto também ajuda o te-x, na medida em que ele agora sabe que nunca deve usar a função getch() em nenhuma circunstância (ou quase nenhuma).
 
Não. O gets() não redimensiona a string, como a função que eu postei. Por isso, imagina que crias uma string de 32 caracteres, mas introduzes 33. Dá asneira, obviamente.
Pois...faltou-me esse pormenor! Já guardei a função para depois ve-la com calma para algum caso de necessidade!!Obrigado!

De certa forma, isto também ajuda o te-x, na medida em que ele agora sabe que nunca deve usar a função getch() em nenhuma circunstância (ou quase nenhuma).
Claro. Vai-se sempre aprendendo! E até podia ser mesmo isso que ele queria, eu só respondi de acordo com a minha interpretação da duvida dele. E assim ficou com a duvida esclarecida com certeza(penso eu).
 
Back
Topo