Por que alguns programas em C rodam no Windows mas não no LINUX? [RESOLVIDO]

1. Por que alguns programas em C rodam no Windows mas não no LINUX? [RESOLVIDO]

Gustavo Samuel Bacagine Azevedo
Bacagine

(usa Arch Linux)

Enviado em 11/07/2019 - 18:38h

Comecei a fazer faculdade de ADS a pouco tempo e migrei para o LINUX logo no começo do ano.
Percebi que alguns programas que criei funcionam no Windows mas não funcionavam no LINUX.
Minha dúvida é:
Por que alguns programas em C rodam no Windows mas não no LINUX?


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 12/07/2019 - 16:17h

Bacagine escreveu:

Minhas dúvidas são:
1) Por que devo usar getchar no lugar de getch?


Porque getch() não é uma função padronizada e, portanto, não existe em qualquer sistema (existe uma getch() no Linux, como parte da biblioteca Curses, mas o comportamento dela é diferente da versão que tem no MS-DOS).

2) Porque devo usar getchar duas vezes (um professor me eplicou uma vez mas acabei esquecendo e gostaria de me lembrar)


O que acontece, tanto no Linux como no Windows, é que geralmente a entra e saída de dados são orientadas a linha. A orientação a linha implica que simplesmente apertar uma tecla não basta para que a a função getchar() retorne imediatamente, porque, por trás de um getchar(), a biblioteca de entrada e saída do C está tentando ler uma linha inteira, e essa tentativa só acaba sendo bem sucedida quando o caráter de fim de linha é encontrado, ou quando acaba o espaço interno de buffer para conter os caracteres encontrados antes do caráter que marca o fim da linha.

Além disso, o caráter de fim de linha, quando encontrado, é colocado no buffer de entrada como parte do conteúdo lido; se ele não for explicitamente consumido pelo seu programa, ficará lá, à espera da próxima operação de leitura. Quando seu programa executa “scanf("%f", &x)”, o que acontece não é a leitura de uma linha inteira e a extração do número de ponto flutuante que está presenta nessa linha; a função scanf() é muito mais complexa que isso — e por isso eu recomendo que sua documentação seja lida com muito cuidado. O que acontece realmente é que a conversão "%f" provoca um descarte de espaços que porventura ocorram antes do número, seguida pela busca de caracteres que possam compor o número, até que seja encontrado o primeiro caráter que não possa ser considerado parte do número. Tal caráter, quando encontrado, não é consumido, mas permanece no buffer de leitura.

Se, no momento da execução, o usuário digitar “2.5”, o programa (isto é: a biblioteca de entrada e saída que seu programa usa) vai continuar aguardando a marca de fim de linha. Quando o usuário aperta a tecla <Enter>, essa marca finalmente injeta o caráter de fim de linha no terminal, e o programa recebe esse caráter e o coloca no buffer. scanf(), por sua vez, vê que a marca de fim de linha não faz parte do número, e grava o valor lido no local apontado, deixando a marca de linha de linha no buffer. Se a operação de leitura seguinte for “scanf("%f", &y), a marca de fim de linha que tinha ficado pendente no buffer será consumida como parte do descarte automático de espaços, antes de começar a consumir os caracteres que compõem o número a ser lido. Se o usuário digitar “1.5” e teclar <Enter>, a conversão var consumir '1', '.' e '5', mas mas deixar o '\n' correspondente à tecla <Enter> no buffer, até a próxima operação de leitura.

Então, se você quiser ler um único caráter, é importante garantir que não haja nenhuma sobra de operações anteriores no buffer.

Fora tudo isso, que está sob o controle do programa em C usando funções padronizadas, o próprio driver do terminal, sob controle do sistema operacional, também emprega buffers, para que o que é digitado não se perca, caso a aplicação que está rodando no terminal demore pedir para a ler o que o usuário digita.

getchar() poderia retornar imediatamente após uma tecla ser apertada. Mas, para isso, você teria primeiro de ter o cuidado de não deixar sobras no buffer, e depois teria de pedir à biblioteca de leitura do C que parasse de usar orientação à linha e pedir ao sistema operacional que altere o comportamento do driver do terminal, a fim de eliminar o efeito dos seus buffers. O primeiro pedido pode ser feito com funções do C padrão; o segundo requereria o uso de funções particulares do seu sistema operacional.

getch() é uma maneira de pedir ao sistema operacional que interaja diretamente com o terminal, sem passar pelo sistema de entrada e saída do C. Misturar getch() com funções de leitura padronizadas do C aplicadas ao terminal é geralmente um erro, inclusive no MS-DOS/Windows.

3) Por que em partes do código como esta não aceitam apenas que eu escreva main():
 else{
main();
}
}while (x != -0);


Queria que caso o usuario não digitasse nenhuma das opções anteriores, o programa mostrasse o que tem na função main, no entanto não consigo fazer isso para o LINUX.


Seria importante ver a mensagem de erro específica que o compilador mostra. Mas eu não consigo pensar em nenhum caso válido pelo qual um programa devesse chamar main() explicitamente. A forma como você fez isso no seu programa denota um erro de modelagem.

A forma correta de fazer em C o que você fez (mantendo as mesmas funções que você fez, embora eu também não ache que elas estão muito bem divididas) seria mais ou menos a seguinte.
bool read_until_eol(void){
int ch;
while((ch=getchar())!=EOF && ch!='\n')
;
return ch=='\n';
}

void input_error(){
if(
ferror(stdin) ||
(fprintf(stderr, "Dados inválidos. Tentando limpar o buffer... "), !read_until_eol())
){
perror("Erro de leitura");
exit(1);
}
fprintf(stderr, "OK.\n");
}

void soma(void){
while(1){
float x, y;
printf("Digite a primeira parcela (ou 0 para encerrar): ");
if(scanf("%f", &x)!=1){
input_error();
fprintf(stderr, "Tecle <Enter> para voltar ao menu principal.");
read_until_eol();
break;
}
else if(x==0.0f)
break;
printf("Digite a segunda parcela: ");
if(scanf("%f", &y)!=1){
input_error();
fprintf(stderr, "Tecle <Enter> para voltar ao menu principal.");
read_until_eol();
break;
}
printf("%f%+f=%f\n\n", x, y, x+y);
}
}

void subtracao(void){ /* Semelhante a soma, com as devidas alterações. */ }

void multiplicacao(void){ /* Semelhante a soma, com as devidas alterações. */ }

void divisao(void){ /* Semelhante a soma, com as devidas alterações. */ }

bool menu(void){
/* Apresenta menu. */
/* Lê opção. */
switch(opcao){
case 1: soma(); break;
case 2: subtracao(); break;
case 3: multiplicacao(); break;
case 4: divisao(); break;
case 0: return false;
}
return true;
}

int main(void){
do {
printf("blablabla... \n");
} while(menu());
return 0;
}



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)

3. Re: Por que alguns programas em C rodam no Windows mas não no LINUX?

berghetti
berghetti

(usa Debian)

Enviado em 11/07/2019 - 19:11h

existem funções/bibliotecas especificas para ambas as plataformas,
você terá que adptar seu código de acordo com a plataforma.



4. Re: Por que alguns programas em C rodam no Windows mas não no LINUX? [RESOLVIDO]

Gustavo Samuel Bacagine Azevedo
Bacagine

(usa Arch Linux)

Enviado em 11/07/2019 - 19:49h

berghetti escreveu:

existem funções/bibliotecas especificas para ambas as plataformas,
você terá que adptar seu código de acordo com a plataforma.


Esse é o problema para mim, não sei como adaptar meus códigos pois, todos os lugares onde procuro para aprender sobre a línguagem (livros e vídeos), as pessoas estão sempre fazendo um código mais voltado para o Windows, e eu acabo não conseguindo aprender línguagem C para LINUX.
Existe algum livro ou algo que eu possa ler para aprender a programar para em C para LINUX?


5. Re: Por que alguns programas em C rodam no Windows mas não no LINUX?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 12/07/2019 - 09:00h

Bacagine escreveu:

Comecei a fazer faculdade de ADS a pouco tempo e migrei para o LINUX logo no começo do ano.
Percebi que alguns programas que criei funcionam no Windows mas não funcionavam no LINUX.
Minha dúvida é:
Por que alguns programas em C rodam no Windows mas não no LINUX?


Porque você provavelmente não está usando C puro (ou seja: apenas a linguagem e as funções da biblioteca definidos nas partes obrigatórias do padrão do C). Muito possivelmente tais programas usam funções de bibliotecas exclusivas do Windows, extensões sintáticas particulares do seu compilador, invocações ao sistema de comandos exclusivos do Windows (por meio da função system()), ou funções que não são partes obrigatórias do padrão do C, que alguns compiladores para Windows implementam, mas outros compiladores não (por exemplo, o polêmico e controverso Anexo K do padrão de 2011, que o Visual Studio traz, mas quase ninguém mais no mundo adota).

Para saber em qual dessas categorias o código de que você está falando se enquadra, só olhando.

Em alguns casos, código pouco portável poderia ser tornado portável com relativamente pouco esforço. No caso de programas introdutórios, frequentemente o que causa erro são coisas supérfluas, que poderiam ser simplesmente suprimidas ou trocadas por funções padronizadas, sem perda significativa de funcionalidade. Mas, de novo, só olhando para saber se esse seria o caso.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


6. Re: Por que alguns programas em C rodam no Windows mas não no LINUX?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 12/07/2019 - 11:21h

Bacagine escreveu:

Esse é o problema para mim, não sei como adaptar meus códigos pois, todos os lugares onde procuro para aprender sobre a línguagem (livros e vídeos), as pessoas estão sempre fazendo um código mais voltado para o Windows, e eu acabo não conseguindo aprender línguagem C para LINUX.


Não existe “C para Windows” e “C para Linux”.

Existe C, que é uma linguagem de programação que pode ser usada para expressar algoritmos computáveis em qualquer sistema de computação (que pode ser desde um supercomputador até um garoto que saiba fazer contas e esteja munido de papel e lápis). Associado à linguagem, o padrão do C define uma biblioteca de funções que podem ser implementadas para permitir a interação com os algoritmos que a linguagem permite expressar.

Isso é o que se costuma chamar de “C puro” ou “C padrão”.

Outra coisa que o padrão do C propõe é um modelo de organização e construção do programa que permite agregar partes compiladas separadamente no mesmo programa. Você mesmo pode criar sua própria biblioteca de funções e tipos agregados de dados para realizar certas operações que você use com frequência, compilar essa biblioteca uma única vez, e depois agregar a funcionalidade dessa biblioteca em vários programas diferentes, sem a necessidade de reescrever o código dela em cada um desses programas.

Digamos que a biblioteca que você escreveu seja de cálculo com matrizes. Ela permite a você colocar no seu programa construções com aspecto mais ou menos como mostrado abaixo (sua funcionalidade em itálicos).
#include "matrizes.h"  // Uso aspas em lugar de “<”/“>” para destacar que a não é um cabeçalho da biblioteca padrão.

int main(void){
matriz A=cria_matriz(3, 4); // Cria matriz com 3 linhas de 4 colunas.
if(!le_elementos_arquivo(A, "c:\\dados\\matriz3x4.txt")){
perror("Não foi possível ler matriz do arquivo");
return 1;
}
matriz A_t=gera_transposta(A);
matriz produto4x4=multiplica(A_t, A), produto3x3=multiplica(A, A_t);
printf("Det(A*×A)=%f\nDet(A×A*)=%f\n", determinante(produto4x4), determinante(produto3x3));
/* ... etc ... */
}


O programa acima é um programa em C? Sim, porque a agregação das partes é feita segundo as regras do C, incluindo sintaxe, declarações de elementos e chamadas a funções.

Isso significa que ele vai funcionar em qualquer máquina tenha um compilador C? Não, a menos que você leve para essa máquina uma cópia da sua biblioteca, para que a compilação possa ser bem sucedida.

Mesmo que, internamente, sua biblioteca use apenas recursos do C padrão, ela se mostra para o restante do programa com uma cara própria (a famosa “interface para programação de aplicações”, ou API, do Inglês “application programming interface”). Para que o programa resultante possa ser produzido, o compilador tem conhecer essa cara, e a implementação das funções em si tem de entrar no executável final. Uma coisa e a outra compõem a sua biblioteca, e nenhuma das duas será reconhecida pelo compilador e pelo linker, a menos que você as coloque na máquina destino.

O que acontece com diferentes sistemas operacionais é bastante parecido. Um compilador que rode no Windows e um que rode no Linux serão ambos capazes de reconhecer os padronizados recursos da linguagem e da biblioteca. Mas elementos específicos de um sistema operacional ou que acompanhem o próprio compilador (isso também existe) não estarão necessariamente disponíveis para o outro.

Existe algum livro ou algo que eu possa ler para aprender a programar para em C para LINUX?


Eu recomendaria que você se dedicasse a aprender C puro primeiro, e a aprendê-lo bem. Depois disso, será mais fácil você entender especificidades de cada sistema diferente.

(Na verdade, eu recomendo mesmo é C++, e a programar com bibliotecas de alto nível, que substituem recursos particularidades de cada plataforma com uma API comum (o Qt é um exemplo de biblioteca assim). A não ser que você seja o cara que trabalha nos níveis internos de implementações das coisas, as interfaces de alto nível geralmente lhe bastarão.)


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


7. Re: Por que alguns programas em C rodam no Windows mas não no LINUX?

João Paulo
princknoby

(usa Arch Linux)

Enviado em 12/07/2019 - 11:34h

Cara, uma "Dica" que eu te daria, é: Tente aprender a criar suas próprias funções, existem muitas "chamadas" que os professores nos ensinam no início que são bem problemáticas e limitadas(em questão de plataforma). Por exemplo, com toda certeza no seu primeiro programa você aprender a usar o:
system("pause"); 


Já tentou usar isso no linux? Não deu muito certo né? Porque system("pause"); chama uma função do sistema, e essa função não está presente no Linux, é uma função do Windows. E isso estou falando apenas do problema em relação a plataforma, existem outros problemas em chamar uma função do sistema apenas para "pausar" o programa.

Então tente criar sua própria função de pausar o programa, dessa forma, você terá uma função que irá funcionar em todas as plataformas acredito eu, tanto eu Windows, quanto em Linux, quanto em Mac. :D

Esperto ter contribuído com algo!


8. Re: Por que alguns programas em C rodam no Windows mas não no LINUX? [RESOLVIDO]

Gustavo Samuel Bacagine Azevedo
Bacagine

(usa Arch Linux)

Enviado em 12/07/2019 - 12:55h

Vou mostrar para vocês um programa que encontrei na internet que rodava em Windows mais não no LINUX junto com a adaptação que fiz para que ele rodasse no LINUX

Código para Windows:

#include <stdio.h>
#include <stdlib.h>

void adicao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("+\n");
scanf("%f", &y);
total = x+y;
printf("=\n");
printf("%.2f\n", total);
getch();
}
else{
main();
}
}while (x != 0);
}
void subtracao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("-\n");
scanf("%f", &y);
total = x-y;
printf("=\n");
printf("%.2f\n", total);
getch();
}
else{
main();
}
}while (x != 0);
}
void multiplicacao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite o primeiro fator:\n");
scanf("%f", &x);
if (x != 0){
printf("x\n");
scanf("%f", &y);
total = x*y;
printf("=\n");
printf("%.2f\n", total);
getch();
}
else{
main();
}
}while (x != 0);
}
void divisao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("/\n");
scanf("%f", &y);
total = x/y;
printf("=\n");
printf("%.2f\n", total);
getch();
adicao();
}
else{
main();
}
}while (x != 0);
}
void menu(){
int opcao;
system("cls");
printf("MENU\n");
printf("1-Adicao\n");
printf("2-Subtracao\n");
printf("3-Multiplicacao\n");
printf("4-Divisao\n");
printf("5-Sair\n");
printf(">>");
scanf("%d", &opcao);
switch (opcao){
case 1:
adicao();
break;
case 2:
subtracao();
break;
case 3:
multiplicacao();
break;
case 4:
divisao();
break;
default:
system("exit");}}
main(){
printf("|||||||||||||||\n");
printf("||CALCULADORA||\n");
printf("||By: Gabriel||\n");
printf("|||||||||||||||\n");
menu();
}



Essa é a adaptação que fiz para rodar no meu SO:

#include <stdio.h>
#include <stdlib.h>

void adicao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("+\n");
scanf("%f", &y);
total = x+y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
}
else{
int main();
}
}while (x != 0);
}
void subtracao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("-\n");
scanf("%f", &y);
total = x-y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
}
else{
int main();
}
}while (x != 0);
}
void multiplicacao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite o primeiro fator:\n");
scanf("%f", &x);
if (x != 0){
printf("x\n");
scanf("%f", &y);
total = x*y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
}
else{
int main();
}
}while (x != 0);
}
void divisao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("/\n");
scanf("%f", &y);
total = x/y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
adicao();
}
else{
int main();
}
}while (x != 0);
}
void menu(){
int opcao;
system("clear");
printf("MENU\n");
printf("1-Adição\n");
printf("2-Subtração\n");
printf("3-Multiplicação\n");
printf("4-Divisão\n");
printf("5-Sair\n");
printf(">>");
scanf("%d", &opcao);
switch (opcao){
case 1:
adicao();
break;
case 2:
subtracao();
break;
case 3:
multiplicacao();
break;
case 4:
divisao();
break;
default:
system("exit");}}
int main(){
printf("|||||||||||||||\n");
printf("||CALCULADORA||\n");
printf("||By: Gabriel||\n");
printf("|||||||||||||||\n");
menu();
}



Minhas dúvidas são:
1) Por que devo usar getchar no lugar de getch?
2) Porque devo usar getchar duas vezes (um professor me eplicou uma vez mas acabei esquecendo e gostaria de me lembrar)
3) Por que em partes do código como esta não aceitam apenas que eu escreva main():
 else{
main();
}
}while (x != -0);


Queria que caso o usuario não digitasse nenhuma das opções anteriores, o programa mostrasse o que tem na função main, no entanto não consigo fazer isso para o LINUX.



9. Re: Por que alguns programas em C rodam no Windows mas não no LINUX? [RESOLVIDO]

João Paulo
princknoby

(usa Arch Linux)

Enviado em 12/07/2019 - 14:22h


Bacagine escreveu:

Vou mostrar para vocês um programa que encontrei na internet que rodava em Windows mais não no LINUX junto com a adaptação que fiz para que ele rodasse no LINUX

Código para Windows:

#include <stdio.h>
#include <stdlib.h>

void adicao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("+\n");
scanf("%f", &y);
total = x+y;
printf("=\n");
printf("%.2f\n", total);
getch();
}
else{
main();
}
}while (x != 0);
}
void subtracao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("-\n");
scanf("%f", &y);
total = x-y;
printf("=\n");
printf("%.2f\n", total);
getch();
}
else{
main();
}
}while (x != 0);
}
void multiplicacao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite o primeiro fator:\n");
scanf("%f", &x);
if (x != 0){
printf("x\n");
scanf("%f", &y);
total = x*y;
printf("=\n");
printf("%.2f\n", total);
getch();
}
else{
main();
}
}while (x != 0);
}
void divisao(){
float x, y, total;
char sn;
do{
system("cls");
printf("OBS: DIGITE -0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("/\n");
scanf("%f", &y);
total = x/y;
printf("=\n");
printf("%.2f\n", total);
getch();
adicao();
}
else{
main();
}
}while (x != 0);
}
void menu(){
int opcao;
system("cls");
printf("MENU\n");
printf("1-Adicao\n");
printf("2-Subtracao\n");
printf("3-Multiplicacao\n");
printf("4-Divisao\n");
printf("5-Sair\n");
printf(">>");
scanf("%d", &opcao);
switch (opcao){
case 1:
adicao();
break;
case 2:
subtracao();
break;
case 3:
multiplicacao();
break;
case 4:
divisao();
break;
default:
system("exit");}}
main(){
printf("|||||||||||||||\n");
printf("||CALCULADORA||\n");
printf("||By: Gabriel||\n");
printf("|||||||||||||||\n");
menu();
}



Essa é a adaptação que fiz para rodar no meu SO:

#include <stdio.h>
#include <stdlib.h>

void adicao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("+\n");
scanf("%f", &y);
total = x+y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
}
else{
int main();
}
}while (x != 0);
}
void subtracao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("-\n");
scanf("%f", &y);
total = x-y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
}
else{
int main();
}
}while (x != 0);
}
void multiplicacao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite o primeiro fator:\n");
scanf("%f", &x);
if (x != 0){
printf("x\n");
scanf("%f", &y);
total = x*y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
}
else{
int main();
}
}while (x != 0);
}
void divisao(){
float x, y, total;
char sn;
do{
system("clear");
printf("OBS: DIGITE 0 PARA SAIR\n");
printf("Digite a primeira parcela:\n");
scanf("%f", &x);
if (x != 0){
printf("/\n");
scanf("%f", &y);
total = x/y;
printf("=\n");
printf("%.2f\n", total);
getchar();
getchar();
adicao();
}
else{
int main();
}
}while (x != 0);
}
void menu(){
int opcao;
system("clear");
printf("MENU\n");
printf("1-Adição\n");
printf("2-Subtração\n");
printf("3-Multiplicação\n");
printf("4-Divisão\n");
printf("5-Sair\n");
printf(">>");
scanf("%d", &opcao);
switch (opcao){
case 1:
adicao();
break;
case 2:
subtracao();
break;
case 3:
multiplicacao();
break;
case 4:
divisao();
break;
default:
system("exit");}}
int main(){
printf("|||||||||||||||\n");
printf("||CALCULADORA||\n");
printf("||By: Gabriel||\n");
printf("|||||||||||||||\n");
menu();
}



Minhas dúvidas são:
1) Por que devo usar getchar no lugar de getch?
2) Porque devo usar getchar duas vezes (um professor me eplicou uma vez mas acabei esquecendo e gostaria de me lembrar)
3) Por que em partes do código como esta não aceitam apenas que eu escreva main():
 else{
main();
}
}while (x != -0);


Queria que caso o usuario não digitasse nenhuma das opções anteriores, o programa mostrasse o que tem na função main, no entanto não consigo fazer isso para o LINUX.


Sobre sua primeira pergunta: https://www.vivaolinux.com.br/topico/C-C++/getch()-no-linux

Sobre a segunda pergunta: Não vai na do seu professor rsrs, aprenda a limpar o buffer corretamente, vou deixar um tópico sobre limpeza de buffer aqui pra você dar uma olhada: https://stackoverflow.com/questions/7898215/how-to-clear-input-buffer-in-c

Sobre sua terceira pergunta: Creio que por mais que você receba um aviso (pois o padrão do main() é int ) acho que você consegue rodar o programa. Nunca passei por isso, mas fazendo uma pesquisa rápida aqui, achei o seguinte, talvez ajude: https://www.portugal-a-programar.pt/forums/topic/6155-resolvido-diferen%C3%A7a-entre-int-main-e-main...

Talvez outro pessoa pode te responder "mais corretamente". Não sou o mais qualificado pra te responder essa questão.


10. Re: Por que alguns programas em C rodam no Windows mas não no LINUX?

Gustavo Samuel Bacagine Azevedo
Bacagine

(usa Arch Linux)

Enviado em 12/07/2019 - 17:59h

Seria importante ver a mensagem de erro específica que o compilador mostra. Mas eu não consigo pensar em nenhum caso válido pelo qual um programa devesse chamar main() explicitamente. A forma como você fez isso no seu programa denota um erro de modelagem.

Esse código não foi feito por mim, eu fiz download dele em um site chamado Script Brasil.
A função main() printa na tela quem foi o criador do código:
int main(){
printf("|||||||||||||||\n");
printf("||CALCULADORA||\n");
printf("||By: Gabriel||\n");
printf("|||||||||||||||\n");
menu();
}

Quando usava Windows o código printava isso na tela, no entanto não consigo fazer isso no LINUX
Essa é a mensagem de erro:
$ gcc Calculadora_Lin.c -o Calculadora
Calculadora_Lin.c: In function ‘adicao’:
Calculadora_Lin.c:22:12: warning: implicit declaration of function ‘main’ [-Wimplicit-function-declaration]
main();
^~~~



11. Re: Por que alguns programas em C rodam no Windows mas não no LINUX?

Gustavo Samuel Bacagine Azevedo
Bacagine

(usa Arch Linux)

Enviado em 12/07/2019 - 18:14h



A forma correta de fazer em C o que você fez (mantendo as mesmas funções que você fez, embora eu também não ache que elas estão muito bem divididas) seria mais ou menos a seguinte.
bool read_until_eol(void){
int ch;
while((ch=getchar())!=EOF && ch!='\n')
;
return ch=='\n';
}

void input_error(){
if(
ferror(stdin) ||
(fprintf(stderr, "Dados inválidos. Tentando limpar o buffer... "), !read_until_eol())
){
perror("Erro de leitura");
exit(1);
}
fprintf(stderr, "OK.\n");
}

void soma(void){
while(1){
float x, y;
printf("Digite a primeira parcela (ou 0 para encerrar): ");
if(scanf("%f", &x)!=1){
input_error();
fprintf(stderr, "Tecle <Enter> para voltar ao menu principal.");
read_until_eol();
break;
}
else if(x==0.0f)
break;
printf("Digite a segunda parcela: ");
if(scanf("%f", &y)!=1){
input_error();
fprintf(stderr, "Tecle <Enter> para voltar ao menu principal.");
read_until_eol();
break;
}
printf("%f%+f=%f\n\n", x, y, x+y);
}
}

void subtracao(void){ /* Semelhante a soma, com as devidas alterações. */ }

void multiplicacao(void){ /* Semelhante a soma, com as devidas alterações. */ }

void divisao(void){ /* Semelhante a soma, com as devidas alterações. */ }

bool menu(void){
/* Apresenta menu. */
/* Lê opção. */
switch(opcao){
case 1: soma(); break;
case 2: subtracao(); break;
case 3: multiplicacao(); break;
case 4: divisao(); break;
case 0: return false;
}
return true;
}

int main(void){
do {
printf("blablabla... \n");
} while(menu());
return 0;
}



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


Tentei compilar seu código com as alterações e apareceu esta mensagem:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/Scrt1.o: na função "_start":
(.text+0x20): referência não definida para "main"
collect2: error: ld returned 1 exit status


O que devo fazer?


12. Re: Por que alguns programas em C rodam no Windows mas não no LINUX? [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 13/07/2019 - 00:50h

Bacagine escreveu:

Tentei compilar seu código com as alterações e apareceu esta mensagem:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/Scrt1.o: na função "_start":
(.text+0x20): referência não definida para "main"
collect2: error: ld returned 1 exit status


O que devo fazer?


Não era para compilar meu código. Ele era apenas um exemplo de como organizar o programa. Em vez de tentar chamar main() para sair de um laço de repetição, o laço de repetição fica na própria main() e vicê retorna a ela ao sair, simplesmente, das funções mais internas.

De todo modo, o que a mensagem de erro indica é que a definição da função main() não foi encontrada no seu programa. Será que você não digitou errado o nome da função, chamando-a de mian(), mani() ou coisa parecida, ou mesmo esqueceu de copiá-la inteiramente?


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)



01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts