[Dúvida] Problemas com o código

1. [Dúvida] Problemas com o código

Letícia Delfino Teixeira
letsdelfino

(usa Outra)

Enviado em 21/10/2016 - 17:15h

Oi, pessoal. Eu sou nova aqui e estou começando a usar o linux e a aprender algumas linguagens de programação.
Estou com um problema em C e estou usando o Kali.

Tenho que fazer uma lista e preciso salvar uma string usando um ponteiro, mas quando o programa começa a executar ele diz que há uma Falha de Segmentação. Segue o código abaixo.

#include<stdio.h>
#include<stdib.h>

typedef struct estru{
struct estru *anterior;
char string[100];
struct estru *abaixo;
struct estru *proximo;
}cliente;

cliente *primeiro = NULL;
cliente *p, *q;

void cadastrar(){
p = (cliente*)malloc(sizeof(cliente));

printf("Nome:\t");
scanf("%s;", p->string);

if(primeiro == NULL){
primeiro = p;
}
else{
q->proximo = p;
p->anterior = q;
}
q->abaixo = NULL;
q = p;
primeiro->anterior = p;
p->proximo = primeiro;
}

main(){
cadastrar();
}


Se alguém puder me dar uma força eu realmente ficaria muito grata!


  


2. Re: [Dúvida] Problemas com o código

Perfil removido
removido

(usa Nenhuma)

Enviado em 21/10/2016 - 17:37h

Não está faltando um #include <stdlib.h> ?

----------------------------------------------------------------------------------------------------------------
Nem direita, nem esquerda. Quando se trata de corrupção o Brasil é ambidestro.
(anônimo)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



3. Re: [Dúvida] Problemas com o código

Letícia Delfino Teixeira
letsdelfino

(usa Outra)

Enviado em 21/10/2016 - 18:31h

Eu declarei no código original. O erro persiste.


4. Re: [Dúvida] Problemas com o código

Perfil removido
removido

(usa Nenhuma)

Enviado em 21/10/2016 - 19:22h

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

typedef struct estru{

struct estru *anterior;
char string[100];
struct estru *abaixo;
struct estru *proximo;
} cliente;

cliente *primeiro = NULL;
cliente *p, *q;

void cadastrar(){

p = (cliente*) malloc(sizeof(cliente));

if (p==NULL) {
printf ("Não foi possível alocar.\n");
exit(1);
}

printf("Nome:\t");
scanf("%s;", p->string);

if(primeiro == NULL){
primeiro = p;
} else{
q->proximo = p;
p->anterior = q;
}

q->abaixo = NULL;
q = p;
primeiro->anterior = p;
p->proximo = primeiro;
}

int main(){
cadastrar();
return 0;
}


Acrescentei algo.
Escrevi o programa separando as linhas e colocando tabulações.
Usei um programa chamado gdb para encontrar onde está dando erro.
O erro é aqui por enquanto:

33		q->abaixo = NULL; 


Depois volto aqui.

----------------------------------------------------------------------------------------------------------------
Nem direita, nem esquerda. Quando se trata de corrupção o Brasil é ambidestro.
(anônimo)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



5. Re: [Dúvida] Problemas com o código

Paulo
paulo1205

(usa Ubuntu)

Enviado em 21/10/2016 - 19:25h

letsdelfino escreveu:

Oi, pessoal. Eu sou nova aqui e estou começando a usar o linux e a aprender algumas linguagens de programação.
Estou com um problema em C e estou usando o Kali.

Tenho que fazer uma lista e preciso salvar uma string usando um ponteiro, mas quando o programa começa a executar ele diz que há uma Falha de Segmentação. Segue o código abaixo.

typedef struct estru{
struct estru *anterior;
char string[100];


O nome “string” pode não ser muito bom. Primeiramente porque não dá nenhuma noção de propósito a quem lê o código. Além disso, é um nome muito comumente usado com macro ou como typedef para supostamente simplificar o uso de strings em geral.

O C++ declara uma classe com esse nome para ter uma representação conveniente de strings. No caso de C++, a chance de conflito de nome seria mais baixa (até porque o nome é std::string), mas pode confundir um leitor humano.

	struct estru *abaixo;
struct estru *proximo;
}cliente;

cliente *primeiro = NULL;
cliente *p, *q;


Os nomes de variáveis talvez pudessem ser melhores.

Se você usar esses ponteiros como meras variáveis temporárias, então possivelmente deveria declará-los como variáveis locais no bloco em que eles forem usados, não como globais.

void cadastrar(){
p = (cliente*)malloc(sizeof(cliente));


Em C, essa conversão de tipo é desnecessária. Sendo desnecessária, o melhor que você faz é evitá-la.

Eu sempre recomendo que a alocação em C seja feita do seguinte modo:

/* Para um dado só. */
ptr=malloc(sizeof *ptr); // A não ser que o tipo de ‘ptr’ seja ‘void *’.

/* Para um array dinâmico com vários elementos */
dyn_array=malloc(n_elementos * sizeof dyn_array[0]);


	printf("Nome:\t");
scanf("%s;", p->string);


Nada errado aqui, mas lembre-se de que lendo desse modo, você não vai poder colocar espaços na string. Além disso, o byte que termina a string (qualquer espaço, incluindo o '\n') vai permanecer no buffer de leitura até a próxima operação.

No entanto, a prudência recomenda que você teste o valor de retorno de scanf().

	if(primeiro == NULL){
primeiro = p;


Não seria melhor definir p->anterior, p->proximo e p->abaixo?

	}
else{
q->proximo = p;


Você está tentando modificar um dado dentro de um objeto apontado por q, mas qual o valor de q nesse momento? Grandes chances de você ter o valor NULL.

		p->anterior = q;
}
q->abaixo = NULL;


Aqui, com certeza q vale NULL, ao menos na primeira inclusão.

	q = p;
primeiro->anterior = p;
p->proximo = primeiro;
}

main(){


A declaração de main deve explicitamente informar o tipo de retorno como int. Quando à lista de argumentos da função, você deve dizer se o seu programa vai trabalhar sem argumentos passados pelo sistema ou se quer receber argumentos passados na forma de um vetor de strings.

No primeiro caso, a declaração deve ter a forma “int main(void)” Se for a segunda opção, a função terá dois argumentos: o primeiro que é do tipo int e indica a quantidade de elementos no vetor de strings, e o segundo que é o vetor de strings. A forma da declaração da função, nesse caso, deve ser “int main(int argc, char **argv)” (os nomes argc e argv são convencionais, você pode optar por outros, desde que mantenha os tipos de cada um).

	cadastrar();
}







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts