Jump to content
Ferreirinha.pt

Falha de segmentação

Recommended Posts

Ferreirinha.pt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>



typedef struct sChamada
{
char *nome;
char *numero;
char tipo;
char *data;
int hora;
int minuto;
int dia;
int mes;
int ano;
} Chamada;


typedef struct sLista
{
Chamada tel;
struct sLista *seg;
} *Lista, nLista;


// testa o numero
int testa(char s[15])
{
int i=0,aux=0,x=0;
while(s[i]!='\0')
{
if(s[i]>='0' && s[i]<='9')
  {aux++;}
i++;
}
x=strlen(s);
x--;
if(x!=aux){return 0;}
else{return 1;}
}



Chamada criachamada ()
{
 char nome2 [24];
 char numero2 [14];
 char tipo2;
 int hora2;
 int minuto2;
 int dia2;
 int mes2;
 int ano2;
 int c=0;
 nome2[0]=32;
 numero2[0]=32;
 Chamada cham;

//nome
printf ("Introduza um nome \n");
 	fgets (nome2,25, stdin);
 	cham.nome = strdup(nome2);
cham.nome[strlen(nome2)-1]='\0';//tira a quebra de linha

//numero
printf ("Introduza um número \n");
while (c==0)
 	{
    fgets (numero2,15,stdin);
    c=testa(numero2);
    if (c==0)
    {printf("Introduza um número válido \n");}
 	} 
 	cham.numero= strdup(numero2);
cham.numero[strlen(numero2)-1]='\0'; //tira a quebra de linha
//Anónimo
 if (numero2[0]=='\n'&& nome2[0]=='\n')
           {cham.nome="Anónimo";}
 if (numero2[0]!='\n' && nome2[0]=='\n')
           {cham.nome= strdup(numero2);}
     //cham.nome[strlen(numero2)-1]='\0'; //tira a quebra de linha

//tipo
 printf("Introduza um tipo: E(fectuada)/R(ecebida) \n");
 	 while(!(tipo2=='E'|| tipo2=='R'))
 	 {
   	  scanf ("%c", &tipo2);
   if (!(tipo2=='E'||tipo2=='R'))
       {printf ("Introduza um tipo válido\n");}
    }
 	cham.tipo =tipo2;
getchar();
//data
printf ("Introduza uma data do tipo dd-mm-aaaa \n");
while (dia2>31&& dia2<01|| mes2>12 && mes2<01 ||ano2<1990 || ano2>2999)
{
 	 scanf ("%d-%d-%d", &dia2, &mes2, &ano2);
 if (dia2>31&& dia2<01|| mes2>12 && mes2<01 ||ano2<1990|| ano2>2999) {printf ("Introduza uma data válida \n");}
}
 cham.dia= dia2;
 cham.mes= mes2;
 cham.ano= ano2;
//hora
dia2=32;
mes2=13;
//printf ("sdggs");
getchar();
//printf("qwerwe");
hora2=25;
printf("Introduza uma hora do tipo hh:ss \n");
while(hora2>23 || minuto2>59)
 {
  scanf("%d:%d", &hora2, &minuto2);
  scanf("%*[^\n]");
         scanf("%*c");
if (hora2>23 || minuto2>59) {printf("Introduza um hora válida\n");}
 }
 cham.hora= hora2;
 cham.minuto = minuto2;
printf ("Contacto gravado.\n");
getchar();
return cham;

}
//alterar acabado
Lista procalt(Lista a, char nomeproc[])
{
if (a!=NULL);
 {
if ((strcmp (a->tel.numero,nomeproc)==0) ||(strcmp(a -> tel.nome,nomeproc)==0)) {return a;}
    else if (a->seg!=NULL) {procalt(a->seg, nomeproc);}
                 else return NULL;
 }
}



void alteraraux(Lista a)
{
char nomeproc[25];
if (a==NULL){printf("A lista está vazia, não pode alterar\n");}
else
{
printf("Insira o nome que deseja alterar: ");
fgets (nomeproc,25, stdin);
nomeproc[strlen(nomeproc)-1]='\0';//tira a quebra de linha
a=procalt(a, nomeproc);
if (a==NULL) {printf("Não encontrou o nome que inseriu pa alterar.");}
else
{
 	  	  char nome2 [24];
	  char numero2 [14];
	  char tipo2;
	  int hora2;
	  int minuto2;
 	  	  int dia2;
	  int mes2;
	  int ano2;
	  int c=0;
	  nome2[0]=32;
	  numero2[0]=32;
	 //nome
 	  printf ("Nome antigo:%s, introduza um novo nome: \n",a->tel.nome);
		 fgets (nome2,25, stdin);
 		  a->tel.nome = strdup(nome2);
	  a->tel.nome[strlen(nome2)-1]='\0';//tira a quebra de linha

	//numero
	  printf ("Numero antigo:%s, introduza um novo numero: \n",a->tel.numero);
	  while (c==0)
 	 	  {
    		fgets (numero2,15,stdin);
    		c=testa(numero2);
    		if (c==0)
    		{printf("Introduza um número válido \n");}
 		  } 
 	  	a->tel.numero=strdup(numero2);
  	a->tel.numero[strlen(numero2)-1]='\0'; //tira a quebra de linha
//Anónimo
  	if (numero2[0]=='\n'&& nome2[0]=='\n')
         		{a->tel.nome="Anónimo";}
  	if (numero2[0]!='\n' && nome2[0]=='\n')
           		{a->tel.nome= strdup(numero2);}
     //cham.nome[strlen(numero2)-1]='\0'; //tira a quebra de linha

//tipo
  	printf("antigo tipo: %c,introduza um novo tipo: E(fectuada)/R(ecebida) \n",a->tel.tipo);
 	  	while(!(tipo2=='E'|| tipo2=='R'))
 	  	{
   	  		scanf ("%c", &tipo2);
  	 	if (!(tipo2=='E'||tipo2=='R'))
  	  		   {printf ("Introduza um tipo válido\n");}
	 	}
 	  	a->tel.tipo =tipo2;
  	getchar();
//data	
  	printf ("data anterior:%d-%d-%d, Introduza uma data do tipo dd-mm-aaaa \n",a->tel.dia,a->tel.mes,a->tel.ano);
  	while (dia2>31&& dia2<01|| mes2>12 && mes2<01 ||ano2<1990 || ano2>2999)
  	{
 	 		scanf ("%d-%d-%d", &dia2, &mes2, &ano2);
 		if (dia2>31&& dia2<01|| mes2>12 && mes2<01 ||ano2<1990|| ano2>2999) {printf ("Introduza uma data válida \n");}
  	}
 	  	a->tel.dia= dia2;
 	  	a->tel.mes= mes2;
 	  	a->tel.ano= ano2;
//hora 	
  	dia2=32;
  	mes2=13;
//printf (	"sdggs");
  	getchar();
//printf("	qwerwe");
  	hora2=25;
  	printf("hora anterior: %d:%d, introduza uma hora do tipo hh:ss \n",a->tel.hora,a->tel.minuto);
  	while(hora2>23 || minuto2>59)
  	{
  		scanf("%d:%d", &hora2, &minuto2);
  		scanf("%*[^\n]");
         		scanf("%*c");
		if (hora2>23 || minuto2>59) {printf("Introduza um hora válida\n");}
 	}		
 	a->tel.hora= hora2;
 	a->tel.minuto = minuto2;
	printf ("Contacto alterado com êxito.\n");
}
}
getchar();
}
//criar Lista
Lista crialista (Chamada a, Lista b)
{
Lista agenda=NULL;
agenda=(Lista)malloc(sizeof(nLista));
agenda->tel = a;
agenda->seg = b;
return agenda;
}

//Imprimir a Chamada no ecrã
void verCha (Lista a)
{
printf("---CONTACTOS---:\nnome:%s\nnumero:%s\ntipo:%c\ndata:%d-%d-%d\nhora:%d:%d\n", a->tel.nome, a->tel.numero, a->tel.tipo, a->tel.dia, a->tel.mes, a->tel.ano, a->tel.hora, a->tel.minuto);
if(a->seg!=NULL){printf("\n");verCha(a->seg);}
}



void ver(Lista abc)
{
if(abc==NULL){printf("A lista está vazia, não pode ver a lista");}
else{
verCha(abc);
}
getchar();
}



Lista procura (Lista a, char nome[])
{if (a->seg !=NULL);
 {
if ((strcmp (a->tel.numero,nome)==0) ||(strcmp(a -> tel.nome,nome)==0)) {return a;}
    else if (a->seg!=NULL) {procura (a->seg, nome);}
                 else return NULL;
 }
}



void procuraaux(Lista a)
{
char nomeproc[25];
if (a==NULL){printf("A lista está vazia, não pode procurar\n");}
else
{
printf("Insira o nome ou número a procurar: ");
fgets (nomeproc,25, stdin);
system("clear");
nomeproc[strlen(nomeproc)-1]='\0';//tira a quebra de linha
a=procura(a, nomeproc);
if (a==NULL) {printf("Não encontrou o nome/numero a procurar.");}
else
{printf("---CONTACTOS ENCONTRADOS---:\nnome:%s\nnumero:%s\ntipo:%c\ndata:%d-%d-%d\nhora:%d:%d\n", a->tel.nome, a->tel.numero, a->tel.tipo, a->tel.dia, a->tel.mes, a->tel.ano, a->tel.hora, a->tel.minuto);
}
}
getchar();
}

/*Lista apagacham(Lista a)
{
char prima[25];
char cunhado;
printf("nome: ");
fgets(prima, 25, stdin);
cunhado = strdup(prima);
if (cunhado == a -> tel.nome)
{
free(
agenda->seg = b;
return Lista
}
*/

/*
//insere
Lista insere (Lista a)
{
Chamada b;
if (a==NULL) {crialista (b,a);}
else if (strcmp (b.nome, a->tel.nome)<0) {;}
    else (if strcmo(b.nome, a->tel.nome>=0)
}
*/


//main
void gravar(Lista a){

 system("clear");
  FILE *fp;

  fp = fopen("basedados","a");
//  fflush(stdin);

  while(a!=NULL){
     fflush(stdin);
     fprintf(fp, "%s\n", a->tel.nome);
     fprintf(fp,"%s\n",a->tel.numero);
     fprintf(fp,"%c\n",a->tel.tipo);
     fprintf(fp,"%d\n",a->tel.dia);
     fprintf(fp,"%d\n",a->tel.mes);
     fprintf(fp,"%d\n",a->tel.ano);
     fprintf(fp,"%d\n",a->tel.hora);
     fprintf(fp,"%d\n",a->tel.minuto);
a=a->seg;
  }

  fclose(fp);
  printf("Dados gravados com exito\n");getchar();
}






Lista ler(Lista a)
{
char nome2[25];
char numero2[25];
system("clear");
FILE *p;
//p=fopen("basedados","wr");
//fclose(p);
printf("asfdsdf");
p=fopen("basedados","r");
printf("asfdsdf");
   int c;
   c = getc(p);
printf("asfdsdf");
while (c!=EOF)
{
	fgets(nome2, 25,p);
printf("asfdsdf");
	fgets(numero2, 25,p);
     		//fscanf(p,"%s\n",numero2);
printf("asfdsdf");
/////////////////////////////////////////////////////////////////////////////////////////------------------------------ERROERROERROERROERROERRO
	a->tel.nome = strdup(nome2);
printf("asfdsdf");
	a->tel.numero = strdup(numero2);      		
printf("asfdsdf");
	fscanf(p,"%c\n",&a->tel.tipo);
     		fscanf(p,"%d\n",&a->tel.dia);
        fscanf(p,"%d\n",&a->tel.mes);
        fscanf(p,"%d\n",&a->tel.ano);
     		fscanf(p,"%d\n",&a->tel.hora);
        fscanf(p,"%d\n",&a->tel.minuto);
 	        putchar(c);
       	c = getc(p);
	a=a->seg;
}

  if (feof(p))
printf("Dados carregados para a memória\n");
   else if (ferror(p))
     puts("ERRO: leitura do ficheiro");

fclose(p);
return(a);
}


int main ()
{

int opp;
opp = -1;
Chamada cham;
Lista des=NULL;
des=ler(des);
getchar();
while (opp!=0)
{
system("clear");
printf("\n\n");
printf("      |-------------------------------------------|\n");
printf("      |----              Bem-vindo            ----|\n");
printf("      |-------------------------------------------|\n");
printf("      |----         Gestão de Chamadas        ----|\n");
printf("      |-------------------------------------------|\n");
printf("      |----           Menu Principal          ----|\n");
printf("      |----    1-> Inserir Chamada            ----|\n");
printf("      |----    2-> Procurar Contacto          ----|\n");
printf("      |----    3-> Ver lista                  ----|\n");
printf("      |----    4-> Alterar Contacto           ----|\n");
printf("      |----    5-> Remover Contacto           ----|\n");
printf("      |----    6-> Gravar num ficheiro        ----|\n");
printf("      |----    0->          Sair              ----|\n");
printf("      |-------------------------------------------|\n");
printf ("Escolha a sua Opção:");
scanf ( "%d", &opp);
getchar();
if(opp==1)
{
system("clear");
cham=criachamada ();
des=crialista(cham, des);
}
else if(opp==2){system("clear"); procuraaux (des);}

else if(opp==3) {system("clear");ver (des);}

else if(opp==4) {system("clear");alteraraux (des);}

else if(opp==6) {system("clear");gravar (des);}

else if(opp==0) {printf("Adeus\n");}

else {printf("A opção não existe\n");getchar();}
}

return (0);
}
 

O programa compila mas ao incovar da Falha de segmentação...

Alguem me pode dizer pk?

Share this post


Link to post
Share on other sites
Localhost

Portanto, tens aí centenas de linhas de código que, supostamente, tu fizeste. Não sabes onde está o problema do teu código e metes aí o código à espera que alguém o leia e que descubra o erro por ti... não achas que podias pôr uns printf's, descobrir onde o está o problema e depois deixar apenas a porção de código onde existe o problema?


here since 2009

Share this post


Link to post
Share on other sites
Ferreirinha.pt

dá falha de segmentação ao ler o ficheiro "basedados"

Share this post


Link to post
Share on other sites
Ferreirinha.pt

e mais: ao tentar correr o programa simplesmente dá falha de segmentação não devolve printf's de nada

Share this post


Link to post
Share on other sites
softklin

Verificaste se o ficheiro abre correctamente? Por exemplo:

fp = fopen("basedados", "a");

if (fp == NULL) {
  printf("Nao consegui abrir a base de dados!\n");
  exit(1);  // sair do programa
}

Para além disso, tenta compilar com a flag -Wall, tens algumas sugestões que poderias seguir.

gcc -g -Wall -o chamadas chamadas.c


Nick antigo: softclean | Tens um projeto? | Wiki P@P

Ajuda a comunidade! Se encontrares algo de errado, usa a opção "Denunciar" por baixo de cada post.

Share this post


Link to post
Share on other sites
Xpirito

Ou fazes como eu. Programas com o Visual C++ da  m ic ro $o ft e fazes debug :)

Para mim o melhor compilador de C c++... :cheesygrin:


Para perguntas idiotas, respostas estúpidas!

Share this post


Link to post
Share on other sites
Xpirito

Bem, como não tinha nada que fazer e a novela já tinha acabado, peguei no teu exercício.

Pareceu-me que a assetion failure no teu caso tinha a ver com falhas na leitura do ficheiro.

Bem, tu no teu código tinhas a função ler();

Lista ler(Lista a)
{
char nome2[25];
char numero2[25];
        system("clear");
        FILE *p;
        //p=fopen("basedados","wr");
        //fclose(p);
...

descomentei isto. Testei. Aqui acabaram os problemas ao ler o ficheiro. Depois reparei no "wr" e fui à documentação e não encontrei esses parametros no fileopen. Encontrei o "r", "w", "a" etc. Usei o "w" Só mesmo para testes. O que me pareceu é que querias gravar em ficheiro os contactos inseridos anteriormente.

Se queres saber mais como trabalhar com o fileopen consulta: http://www.cplusplus.com/reference/clibrary/cstdio/fopen/

"w+" Create an empty file for both reading and writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file.

Para perguntas idiotas, respostas estúpidas!

Share this post


Link to post
Share on other sites
Diutsu

Usa o GDB para fazer debug nisso.

exacto:

começas com gdb $nome_do_programa

acrescenta uns breakpoints em sitios chave do código : b $ficheiro:$linha

corre o programa com: run (ou só r), se precisares de argumentos para o programa faz: r $arg1 $arg2

faz os prints da informação que tens guardada (quando parares num breakpoint): p $nome_variavel

  até podes fazer comboios como: p node->next()->next()->next()->next()->next()->next()->next()

usar step e next e continue para executares instrução-a-instrução, linha-a-linha ou até ao proximo breakpoint

e caso tenhas segmentation fault não te esqueças de fazer backtrace: bt

custa, mas fazer debug de printf é mais complicado, e assim não tens problemas do género: "se eu tirar este printf daqui ele já não corre" (riam-se mas é verdade, já me aconteceu).


XX SINFO - Semana Informática

Share this post


Link to post
Share on other sites
KTachyon

O erro é (quase de certeza) não conseguires abrir o ficheiro para leitura e, quando chegas a

c = getc(p);

pimba! Segmentation fault. :)

EDIT: Já agora, a razão para não conseguires ver os printfs é porque o programa não chega a fazer flush ao print buffer antes de ter sido forçado a sair. O truque é colocares um '\n' no final do printf. Assim já deverá fazer o flush.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.