Ir ao conteúdo
  • Cadastre-se

C Comandos em C inexistentes - em Linux


Ir à solução Resolvido por kgin,

Posts recomendados

using namespace std;

//BIBLIOTECAS
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <cstring>

//CONSTANTES


//VARIAVEIS


//SUBROTINAS


int main()
{
  int valor = 0;
  char palavra[15], inversa[15];
  cout<<"\nDigite uma palavra ou número: ";
  gets(palavra);
  
  for(int i = 0; palavra[i]; i++)
  {
    palavra[i] = tolower(palavra[i]);
  }
  strcpy(inversa, palavra);
  strrev(inversa);
  valor = strcmp(palavra, inversa);
  if(valor == 0)
  {
    cout<<"\n\n"<<palavra<<"é palíndromo\n";
  }
  else
  {
    cout<<"\n\n"<<palavra<<"não é palíndromo\n";
  }
}

meu código está correto, pois copiei da internet, com leves mudanças, mas não compila:

usuario@maquina:~/Programação/C/Desafios/$ g++ Palindromos.c -o Palindromos


Palindromos.c: In function ‘int main()’:
Palindromos.c:24:3: error: ‘gets’ was not declared in this scope; did you mean ‘fgets’?
   24 |   gets(palavra);
      |   ^~~~
      |   fgets
Palindromos.c:31:3: error: ‘strrev’ was not declared in this scope; did you mean ‘strsep’?
   31 |   strrev(inversa);
      |   ^~~~~~
      |   strsep

substitui o gets por fgets, mas apareceu esse erro:

Palindromos.c:24:16: error: too few arguments to function ‘char* fgets(char*, int, FILE*)’
   24 |   fgets(palavra);
      |                ^
In file included from /usr/include/c++/10/cstdio:42,
                 from /usr/include/c++/10/ext/string_conversions.h:43,
                 from /usr/include/c++/10/bits/basic_string.h:6545,
                 from /usr/include/c++/10/string:55,
                 from /usr/include/c++/10/bits/locale_classes.h:40,
                 from /usr/include/c++/10/bits/ios_base.h:41,
                 from /usr/include/c++/10/ios:42,
                 from /usr/include/c++/10/ostream:38,
                 from /usr/include/c++/10/iostream:39,
                 from Palindromos.c:4:
/usr/include/stdio.h:564:14: note: declared here
  564 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
      |              ^~~~~

o que eu poderia fazer para compilar corretamente?

 

Edit: Ah, aquelas milhões de bibliotecas são propositais :)

Edit2: tentei <string.h> E <cstring>, nenhuma melhorou na compilação

  • Confuso 1
Link para o comentário
Compartilhar em outros sites

@Um mero usuário gets é uma função de stdio.h, mas evite usar. Esta função não é recomendada e alguns compiladores mostram um warning assim,

 

warning: the `gets' function is dangerous and should not be used

 

No lugar de gets você pode usar fgets (também de stdio) que permite limitar a quantidade de caracteres. Mas você está misturando C com C++. Se for fazer em C remova a linha do namespace e use a stdio com printf no lugar de iostream e cout.

 

A função strrev não é padrão C e não tem em todos os compiladores, mas você pode criar uma com o mesmo recurso.

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

@Um mero usuário

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

meu código está correto, pois copiei da internet

copiar da internet != estar correto :)

 

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

substitui o gets por fgets, mas apareceu esse erro

Sim, fgets() tem mais parâmetros que gets(), portanto:

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

too few arguments to function ‘char* fgets(char*, int, FILE*)’

Veja a documentação, e descobrirá como chamar a função corretamente:

gets()

fgets()

Como mencionado por @Midori , não use gets(), é obsoleta e não é tão segura quanto a fgets().

 

Como mencionado por @Midori também, você está usando alguns cabeçalhos pertencentes à biblioteca padrão do C, e outros da biblioteca padrão do C++.

 

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

Ah, aquelas milhões de bibliotecas são propositais

Não entendo como...

 

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

tentei <string.h> E <cstring>, nenhuma melhorou na compilação

O primeiro é da biblioteca padrão do C, o segundo do C++.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

  • Solução

@Um mero usuário  Se você estiver no linux eu recomendo usar uma combinação de VScode + C/C++ IntelliSense, se configurado corretamente ele vai apontar o erro antes mesmo de você compilar o código.

 

Se não puder usar o VScode nessa configuração, experimente o site replit.

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

2º qual a diferença dos comandos C e C++? Os 2 compilaram para mim...

São linguagens diferentes que um dia foram a mesma, mas agora não tem nada a ver uma com a outra.

E elas só compilam porque talvez o seu gerenciador de pacotes instalou os dois compiladores (GCC , G++) na maquina.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Um mero usuário

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

1º como @Midori disse, posso substituir "strrev", mas pelo que?

Bem... Basta um loop varrendo a string, inverta a mesma, ou seja, identifique o último caractere (sem ser o caractere nulo) e o primeiro, e os troque, depois identifique o penúltimo e o segundo e faça a troca, etc. Isso é só uma ideia.

 

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

2º qual a diferença dos comandos C e C++? Os 2 compilaram para mim...

C e C++ são linguagens de programação, e você não deveria misturá-las. Pra resumir é isso.

aparentemente funcionar != estar correto

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

9 horas atrás, Lucca Rodrigues disse:

@Um mero usuário

(...) identifique o último caractere (sem ser o caractere nulo) e o primeiro, e os troque (...)

só para me orientar, qual seria o caracter de espaço depois do nulo? tipo assim: string cabe 10, eu coloco banana... fica b|a|n|a|n|a|/0|sobra|sobra|sobra.. o que estaria ali na "sobra"?

 

muito obrigado gente, vocês me ajudaram muito :)

Link para o comentário
Compartilhar em outros sites

12 horas atrás, Um mero usuário disse:

2º qual a diferença dos comandos C e C++? Os 2 compilaram para mim...

Há diferenças entre as linguagens, uma delas é o paradigma. C p.ex suporta o procedural e C++ além disso suporta orientação a objetos. Com um compilador de C++ você pode programar no "estilo C", mas se tivesse criado uma classe não conseguiria compilar com um de C. E cada uma tem sua biblioteca padrão, 

 

https://pt.wikipedia.org/wiki/Biblioteca_padrão_do_C

 

https://pt.wikipedia.org/wiki/Biblioteca_padrão_do_C%2B%2B

 

12 horas atrás, Um mero usuário disse:

disse, posso substituir "strrev", mas pelo que?

Pode ser como @Lucca Rodrigues comentou e a sua função pode ter o mesmo protótipo: char *strrev(char *str);

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Midori disse:

Com um compilador de C++ você pode programar no "estilo C", mas se tivesse criado uma classe não conseguiria compilar com um de C.

Agora fez mais sentido, estava usando o "g++", não o "gcc" hahah

 

2 horas atrás, Midori disse:

char *strrev(char *str);

qual é a dos asteriscos ali? nunca usei isso nos projetos de C/C++

Link para o comentário
Compartilhar em outros sites

@Um mero usuário

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

qual é a dos asteriscos ali?

São ponteiros... Em C só existe passagem por valor, então pra "simular" uma passagem por referência, a gente usa ponteiros.

Colocando char *str como parâmetro na função, você consegue modificar o argumento passado na chamada da função.

Acho que o retorno de strrev é a string depois de invertida.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

12 horas atrás, Lucca Rodrigues disse:

Em C só existe passagem por valor, então pra "simular" uma passagem por referência, a gente usa ponteiros

 

Simular escrito entre aspas é algo engraçado, afinal aspas tentam muitas vezes justamente passar essa noção de aparência, de quase. Uma "verdade" :D entre aspas.

 

C foi escrita para desenvolvimento de sistemas --- um sistema na verdade --- e a opção foi de usar * para indicar o valor apontado e & para pegar o endereço de algo.

 

Como uma referência é um valor, talvez esse tipo de afirmação não ajude muito a entender. Sim, já li isso de muitos autores sérios, mas não consigo entender o sentido. Ok, Pascal por exemplo tem var e call by value e call by reference mas foi escrita por um professor para mostrar a ideia dele para ensinar sobre como devia ser uma linguagem e tal. Algol também era assim.

 

E Pascal é chato. Já leu o Pascal User Manual And Report e as explicações do Prof. Dijskstra para var e Pascal de um modo gerall? Ele, o autor, também era chato. :D Eu programei muito em Pascal e em geral as vantagens (e eu podia usar as ASPAS aqui) eram mais um obstáculo para chegar a um resultado do que um apoio.

 

Passagem de parâmetros implica em parâmetros ou não teria o que passar. Os parâmetros podem ser endereços de coisas ou podem ser coisas. Mas os parâmetros são valores. Se você programar em Assembler antes de aprender Pascal vai ficar furioso por exemplo. Se passar de Assembler para C vai achar que tudo faz sentido. Já participei de discussões assim em bares. Ok, aqueles bares cheios de gente de desenvolvimento :D e sempre achei divertido.

 

13 horas atrás, Um mero usuário disse:

qual é a dos asteriscos ali? nunca usei isso nos projetos de C/C++

 

Ao declarar um trem usando * em C indica que o nome declarado conterá o endereço de uma variável do tipo declarado. E ao usar isso em uma expressão indica que se quer o conteúdo do alvo.

 

Esse conceito é essencial em C ( e Assemble r): saber a diferença do que tem em um endereço de memória é muitas vezes um problema do programa. Um endereço pode ter qualquer coisa. Algumas linguagens controlam mais, outras menos. C menos. E em C se consegue mais em menos tempo, e possivelmente por isso as linguagens que controlam mais são escritas... em C.

 

Nesse trecho

 

    int*    A = NULL; [1]
    int		B = 33; [2]
	
    A = &B; [3]

    int C = *A; [4]
    

 

  • [1] A é uma variável que contém um ponteiro para um inteiro, o tipo de A é int*. Inicialmente não aponta para nada. NULL é uma convenção e vale mesmo 0 que não é endereço de nada.
  • [2] B é do tipo int e o compilador vai garantir o valor 33 lá no programa
  • [3] O operador & é o inverso do *, e vai colocar no endereço de A o endereço de B
  • [4] C é do tipo int e o asterisco do lado esquerdo de A é o contrário de & e vai pegar o valor encontrado no endereço que está em A (pois é, A é um ponteiro) e atribuir para C, que passa a valer 33

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

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