Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

AndreFonseca

Problemas com Struct, Alocaćão Dinâmica e Ponteiros.

Recommended Posts

Aí moćada, to com sérios problemas.

 

Primeiro vamos comećar do princípio: strings.

Qual a diferenća de declarar:

char *nome;
e

char nome[]
?

 

Se eu declarar da primeira maneira eu teria que usar alocaćão dinâmica de memória?

 

Certo. Agora para ler:

scanf("%s", &nome)
ou

scanf("%[^\n]", &nome)
ou

scanf("%[A-Z a-z]", &nome)
ou

gets(nome)
?

 

Se eu usar a primeira forma, ele nao pega os espaćos, e no caso de cadastramento de pessoas eu precisaria de espaćos, certo?

Na segunda forma ele compila e roda, mas acontece que ele pede o RA direto. Na terceira, mesma coisa.

No gets(nome) acontece severos problemas.

Por exemplo:

Uma struct com nome e RA.

Ele nao le o primeiro nome. E pede pra colocar o RA. Daih ele nao le o segundo (porque nao da tempo de escrever) e pede o segundo RA. Entao ele nao armazena nomes.

 

Tá. Esses daí já são só os problemas de string com struct.

 

Agora vem os problemas de string com alocaćão dinâmica.

Se eu fizer char *nome, eu tenho que fazer alocaćão?

Se tiver, como e faćo?

 

Só esses.

 

Com Alocaćão e Struct é o seguinte.

Eu faćo da seguinte forma:

 

#include <stdio.h>#include <stdlib.h>typedef struct {	char nome[30];	int RA;} Aluno;void apresenta(int, Aluno *);main (){	Aluno *aluno;	int i, quantidade, pos;	system("clear");	printf("Digite a quantidade de alunos que deseja cadastrar: ");	scanf("%d",&quantidade);	aluno = (Aluno *)malloc(quantidade*sizeof(Aluno));   // qual é a certa pra utilizar?	//aluno = (Aluno *)malloc(quantidade);	  // qual é a certa pra utilizar?	system("clear");	for (i = 0; i < quantidade; i++)	{		printf("Digite o nome do aluno numero %d: ",i+1);		scanf("%s", &aluno[i].nome);   // só pega o primeiro nome. como fazer pra pegar espaços?		//gets(aluno[i].nome);	 // tá pulando todos os nomes.		printf("Digite o RA do aluno: ");		scanf("%d", &aluno[i].RA);		system("clear");	}

Meu código tá praticamente assim.

As dúvidas estão nos comentários.

 

Tem como alguém me ajudar?

 

 

Valeu, abrassss e desculpem-me os erros de portugues, é que eu to no slackware e esse coco ta desconfigurado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiro vamos comećar do princípio: strings.Qual a diferenća de declarar:

char *nome;
e
char nome[]
?Se eu declarar da primeira maneira eu teria que usar alocaćão dinâmica de memória?
Na realidade as duas formas de declaracão de seu vetor te retorna um ponteiro e com tamanho indefinido, portanto o ideal é alocar nos dois casos.

Se eu declarar da primeira maneira eu teria que usar alocaćão dinâmica de memória?Certo. Agora para ler:

scanf("%s", &nome)
ou
scanf("%[^\n]", &nome)
ou
scanf("%[A-Z a-z]", &nome)
ou
gets(nome)
?
o uso de gets não é recomendado, essa funcão facilmente estou buffer causando buffer overflow.para leitura de string o & é dispensável.
scanf("%s", nome)
armazena na variável até encontrar um enter ou um espaco em branco.
scanf("%[A-Z a-z]", nome)
le somente letras e espaco em branco, qualquer coisa além não é armazenado na variável.
scanf("%[^\n]", nome)
armazena na variável até achar "\n".

Compartilhar este post


Link para o post
Compartilhar em outros sites

Poisé cara.

Mas nenhuma dessas deu certo.

 

Só a primeira:

 

scanf("%s", &nome)

Mas não pega os espaços. Você fez ali sem o & (e comercial). Ele funciona assim?

 

E o resto delas só passa reto :(

 

Não sei mais o que fazer.

Amanhã de manhã vou estudar bastante isso. Tenho que fazer um exemplo de thread (que não sei como vou fazer) em C ou em Java, mas Java meu professor usa BlueJ :( :( :(, então acho que é muito mais chato de implementar e coisarada. E C é muito mais próxima do hardware do que Java (eu acho que sim pelo menos).

 

Abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Poisé cara.Mas nenhuma dessas deu certo.Só a primeira:

scanf("%s", &nome)
Mas não pega os espaços. Você fez ali sem o & (e comercial). Ele funciona assim?
funciona sim cara.tente trocar de compilador.acabei de testar no DevC++:
#include <stdio.h>#include <conio.h>int main(){	char nome[30];	printf("Digite um nome\n");	scanf("%[A-Z a-z]", nome);	printf("Voce digitou: %s", nome);	getch();		return 0;}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, ele funciona.

 

Mas veja como fica meu programa com a struct e coisarada:

 

#include <stdlib.h>typedef struct pessoa {	int cpf;	char nome[50];	int idade;	} Pessoa;	main (){	Pessoa *cadastros;	int i, qtdade;		printf("Digite a quantidade de pessoas que deseja cadastrar: ");	scanf("%d", &qtdade);	cadastros = (Pessoa *)malloc(qtdade*sizeof(Pessoa));	system("cls");	for (i = 0; i < qtdade; i++)	{		printf("Digite o nome da pessoa %d: ",i+1);		scanf("%[A-Z a-z]", cadastros[i].nome);		//gets(cadastros[i].nome);		printf("Digite o cpf da pessoa %d: ",i+1);		scanf("%d", &cadastros[i].cpf);		printf("Digite a idade da pessoa %d: ",i+1);		scanf("%d", &cadastros[i].idade);		system("cls");	}

Ele não tá completo nem nada, mas ele em vez de ler o nome ele passa reto e le o CPF.

 

É por causa da alocação dinâmica de memória que o array de cadastros recebe?

 

cadastros = (Pessoa *)malloc(qtdade*sizeof(Pessoa));

?

 

Muito obrigado.

Abraço!

 

E você poderia me responder também sobre esse programa?

 

#include <stdio.h>#include <stdlib.h>main (){	char *nome;	//char nome2[];		  // não compila	printf("*nome: ");	scanf("%[A-Z a-z]", nome);	//scanf("%s", &nome);	// não recebe	//gets(nome);			// não recebe	//scanf("%[%[^\n]s",nome); // não recebe	printf("%s", nome);}

O *nome ali está errado?

Se eu fizesse

 

char nome2[];

Ele não compila. Então eu teria que fazer alocação dinâmica para colocar o tamanho da string ali dentro? Mas não teria como ler daí :-

 

QUANTA CONFUSÃO!! MINHAS ARMA!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ele não tá completo nem nada, mas ele em vez de ler o nome ele passa reto e le o CPF.É por causa da alocação dinâmica de memória que o array de cadastros recebe?

cadastros = (Pessoa *)malloc(qtdade*sizeof(Pessoa));
?
não é não.aqui no dev funciona dos dois jeitos, mas altere a linha abaixo e faça o teste.
scanf("%[A-Z a-z]s", cadastros[i].nome);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tentei e não deu certo :(

 

Pra te falar bem a verdade, não deu certo em 2 compiladores de "respeito": GCC e a IDE Microsoft Visual 4.

 

Hoje na aula, meu amigo conseguiu fazer dar certo. Ele usa o

 

scanf("%[^\n]",&cadastros.nome);

Acontece que no meu e no dele passava reto, sabe? Então ele deu um getchar() antes de entrar no nome, daí funcionou.

Estou na faculdade, mas quando chegar em casa eu implemento e vejo se dá certo.

 

Na monitoria a tarde, o monitor tentou da mesma maneira e deu a mesma coisa.

Só que quando ele não pergunta a quantidade, e deixa um valor fixo em qtdade, roda legal, com gets e com scanf :(

 

Por que será?

 

Valeu cara, abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acontece que no meu e no dele passava reto, sabe? Então ele deu um getchar() antes de entrar no nome, daí funcionou.Estou na faculdade, mas quando chegar em casa eu implemento e vejo se dá certo.Na monitoria a tarde, o monitor tentou da mesma maneira e deu a mesma coisa.Só que quando ele não pergunta a quantidade, e deixa um valor fixo em qtdade, roda legal, com gets e com scanf sad.gifPor que será?

É porque o enter fica no buffer e como o próximo scanf é instruído a ler somente letras e espaço ele pula a execução do scanf que lê o nome.O getchar resolve ou force a limpeza do buffer com fflush(stdin).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pois é cara.Só uma última dúvida... ess buffer que você falou, é algum recurso que fica no dispositivo de entrada (interface do teclado) ou da memória?Valeu, abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pois é cara.Só uma última dúvida... ess buffer que você falou, é algum recurso que fica no dispositivo de entrada (interface do teclado) ou da memória?Valeu, abraço!

Buffer do teclado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pois é cara.Só uma última dúvida... ess buffer que você falou, é algum recurso que fica no dispositivo de entrada (interface do teclado) ou da memória?Valeu, abraço!

Buffer do teclado.
USE fflush (stdin) ou system ("CLS")em struct é imprecindível o uso.se não passa reto mesmo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

o uso de gets não é recomendado, essa funcão facilmente estou buffer causando buffer overflow.

Pode explicar como/porque facilmente causa buffer overflow?

Seria assim, você tem uma string s[5], ai pede pra entrar com um texto, e é entrado AAAAAAAAAA, nesse caso ocuparia 5 espaços da memória não alocada? Usando scanf sem nenhum tratamento(como algum dos indicados anteriormente) teria o mesmo problema então neh? Só usando fgets() pra tapar essa brexa?

Compartilhar este post


Link para o post
Compartilhar em outros sites
O getchar resolve ou force a limpeza do buffer com fflush(stdin).

 

De novo: fflush so tem comportamento definido para stdtout. Qualquer coisa p/ stdin é extensão do padrão.

 

http://www.guiadohardware.net/comunidade/l...-buffer/739172/

http://www.drpaulcarter.com/cs/common-c-errors.php

http://www.iso-9899.info/wiki/Implementation

 

Segundo o manual do FreeBSD (e do Suse na maquina virtual) : http://www.freebsd.org/cgi/man.cgi?sektion...mp;query=fflush

 

The function fpurge() erases any input or output buffered in the given stream. For output streams this discards any unwritten output. For input streams this discards any input read from the underlying object but not yet obtained via getc(3); this includes any text pushed back via ungetc(3).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse post é de um ano e meio atrás.

Eu usei por muito tempo o gcc para fazer meus programas e sempre usei fpurge.

Quando precisei usar o dev eu comecei a usar fflush simplesmente por encontrar uma referencia de como limpar o buffer no windows.

Depois de um tempo eu li a man page do fflush e descobri que era um erro usa-lo para executar essa funcionalidade.

Infelismente não tenho como editar todos meus posts e pedir desculpas por esse erro.

 

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acontece que o groove deu up no tópico.Se alguem passar e ler sobre o fflush ja fica avisado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Já que ele ressucitaram o tópico, voce conhece algo para limpar o buffer de entrada no windows?

O fpurge não funciona a não ser que esteja definido em alguma biblioteca que eu não tenha usado.

O que sugere?

 

Acontece que o groove deu up no tópico.Se alguem passar e ler sobre o fflush ja fica avisado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

http://msdn.microsoft.com/en-us/library/ms683147(VS.85).aspx

 

Não uso o windows p/ programar, mas o dia q eu achar um livro decente sobre a Win32 API (porque documentacao online é só referencia) eu comeco.

A verdade tambem é que programacao ou é via IDE ou você tem que sofrer pra deixar o terminal usável e editar as coisas com o Edit é pedir pra morrer (a falta de um editor tipo o Kate,KWrite ou GEdit é grande)

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.