Ir ao conteúdo
  • Cadastre-se

C Programa que pede nome e exibe na tela


fwanti
Ir à solução Resolvido por arfneto,

Posts recomendados

Comecei a estudar C recentemente e estou tentando criar um código pra pedir o nome de um usuário, e o exibe na tela.

O meu código é esse(uso Visual Studio, por ser obrigatório no curso):

 

#include <stdio.h>
#include <locale.h>


int main() {

	setlocale(LC_ALL, "portuguese");
	
	char nome[20];

	printf("Diga seu nome\n");
	scanf_s("%s", &nome);
	printf("Seu nome é %s", nome);
		




	return 0;
}

 

 

Sempre que executo e digito um nome aleatório ele dá o seguinte erro:

 

Erro.PNG.bfcc78304ab79aeb42dc331b9e41d563.PNG

 

 

 

 

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

  • Solução

Leia o manual, sempre. 

 

Basta parar o cursor sobre a função e ficar olhando....

 

image.png.9cf5fb22593ade66b0010cd8a337d775.png

 

Pois é. E em português se o idioma estiver instalado no Visual Studio

 

E se tem mais duvidas tem o Search Online que em geral vai direto para o manual...

 

Em português na documentação nesse caso

 

Mas apenas o que está na tela deveria ser suficiente: scanf_s() tem o que scanf() deveria ter desde o início: um argumento a mais para cada campo, especificando o tamanho. Pela mesma razão gets() foi praticamente banida em função de fgets() 20 anos atrás. Mas por uma questão política a Microsoft nunca conseguiu por isso no padrão.

 

E o que está escrito lá? C6064: Falta argumento inteiro para scanf_s(), correspondente ao especificador 2, no popular o segundo.

 

image.png.d48948a2b29a362c500128c6ab5777dc.png

 

Seguindo o manual e o que está escrito na mensagem de erro:

 

Note que ao seguir a documentação e colocar o tamanho do campo a mensagem de erro desaparece e o programa roda.

 

 

 

 

Você pode também usar a implementação original de scanf() se precisa por exemplo compilar também no MAC ou no Linux e não quer manter dois programas ou um #define chato

 

apenas configure a opção _CRT_SECURE_NO_WARNINGS para seu projeto.

 

Como eu sei isso? Basta compilar um programa que chama scanf() no Visual Studio e ficar olhando na tela...

 

Usando

 

    scanf("%s", nome);

 

e compilando o programa vem 

 

or-0831.c(10): warning C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead. 
To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

 

Pois é. Se usa em português a mensagem vem em português. C4996 e o que diz? está função pode ser insegura. Considere usar scanf_s como opção. Para desabilitar obsolescência use _CRT_SECURE_NO_WARNING. Para detalhes veja a ajuda online.

 

Sua opção foi por usar scanf_s() mas você não foi ver a diferença. Só trocou o nome... ???

 

E o outro caso?  Apenas use nas opções do projeto o que está escrito lá na mensagem, sem stress.

 

E onde?  Mas propriedades do projeto, claro. Vá em C/C++, definições para o pre-processador e marque exatamente o que está escrito na mensagem e que, lógico, você pode copiar com control-C...

 

image.png.70817cc8626420819a9b8301c77508d1.png

 

Ou use um #define 

 

#define      _CRT_SECURE_NO_WARNINGS

 

Em cada código em que chama alguma dessas funções inseguras, exceto gets() que não vai mesmo rolar.

 

E sobre sua chamada a scanf() scanf_s()

 

	char nome[20];
	printf("Diga seu nome\n");
	scanf_s("%s", &nome);

 

Entenda: scanf() não aloca memória. Você precisa fornecer o endereço para a função transferir cada valor lido.

 

No seu caso só lê um, então precisa de um endereço para onde transferir o que ler com o especificador "%s". Mas no caso de nome, nome é char[] e assim nome sozinho é o endereço de início do vetor, já é um ponteiro para uma variável estática, alocada ali mesmo duas linhas acima, e assim você não usa o operador &. nome já é um ponteiro.

 

TL;DR:  use 
 

    scanf_s("%s", nome, 20 );

 

Não entendo como um curso que sugere o uso de Visual Studio não explica no mínimo isso. Acho que devia se queixar com seu instrutor. :) 

 

Um exemplo mais longo :) 

 

#include <locale.h>
#include <stdio.h>
int main()
{
    setlocale(LC_ALL, "portuguese");
    char nome[20];
    unsigned i = 42;
    char     c;

    printf("Diga seu nome, letra e numero ");
    scanf_s("%s %c %u", nome, 20, &c, 1, &i );
    printf("nome \"%s\", letra '%c' e numero %d",
        nome, c, i );
    return 0;
}

 

mostra

 

Diga seu nome, letra e numero Clube X 42
nome "Clube", letra 'X' e numero 42

 

atente para as diferenças...

 

 

 

 

 

 

image.png

Link para o comentário
Compartilhar em outros sites

@arfneto Primeiro vou te agradecer, porque resolveu meu problema, mas além disso eu aprendi sobre o funcionamento tanto do scanf quanto do scanf_s bem fácil.

24 minutos atrás, arfneto disse:

Pois é. Se usa em português a mensagem vem em português. C4996 e o que diz? está função pode ser insegura. Considere usar scanf_s como opção. Para desabilitar obsolescência use _CRT_SECURE_NO_WARNING. Para detalhes veja a ajuda online.

Eu realmente não sabia que isso era uma opção, de verdade isso foi uma ajuda bem grande.

 

25 minutos atrás, arfneto disse:

Mas apenas o que está na tela deveria ser suficiente: scanf_s() tem o que scanf() deveria ter desde o início: um argumento a mais para cada campo, especificando o tamanho

Isso que me pegou de surpresa, quando comecei a estudar C, o professor utilizou o Python como referência:

 

print é semelhante a printf

input é semelhante a scanf/scanf_s

 

Ele explicou que scanf_s era simplesmente uma mudança de sintaxe da Microsoft, e não que tinham diferença prática. Até pesquisei no reddit em alguns tópicos, mas muitos apenas estavam constatando que o scanf_s não tem diferença prática do scanf. Agora eu sei que tem essa diferença básica (mas muito útil).

Link para o comentário
Compartilhar em outros sites

7 minutos atrás, fwanti disse:

Ele explicou que scanf_s era simplesmente uma mudança de sintaxe da Microsoft, e não que tinham diferença prática. Até pesquisei no reddit em alguns tópicos, mas muitos apenas estavam constatando que o scanf_s não tem diferença prática do scanf. Agora eu sei que tem essa diferença básica (mas muito útil).

 

Seu professor estava errado.

 

Dá pra desconfiar que não podia ser só mudar o nome...

 

E não é uma mudança de sintaxe. É um conjunto de versões seguras --- safe versions --- para várias dessas funções que tratam fluxos --- streams --- como printf() e fscanf().

 

10 minutos atrás, fwanti disse:

Eu realmente não sabia que isso era uma opção, de verdade isso foi uma ajuda bem grande.

 

Mas isso sai na tela em TODO programa que você compilar chamando por exemplo scanf()...

 

11 minutos atrás, fwanti disse:

Até pesquisei no reddit em alguns tópicos, mas muitos apenas estavam constatando que o scanf_s não tem diferença prática do scanf

 

Pesquise antes de tudo no próprio ambiente. A documentação do Visual Studio é enorme e está sempre ali... E no reddit ninguém é responsável por nada, nem nos forums.  

 

Na Microsoft os funcionários escrevem ;) a documentação. Funcionários são como C, tem muitas funções e um main(), o chefe.

 

Use o C++Reference também. é bem completo e quase oficial.

 

 

 

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

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!