dúvidas usando arquivo.h struct e ponteiros, tudo junto

Programação C em geral

Moderadores: 51, guest2003

dúvidas usando arquivo.h struct e ponteiros, tudo junto

Mensagempor bfccardoso » 23 Jan 2009 10:38

estou tentando aprender o máximo possível de C pois vou começar a trabalhar com um ARM7 no mês que vem, só que cheguei em um ponto de um programinha que não consigo sair de jeito nenhum, quando eu uso o DEBUG, da o seguinte erro:
Uma violação de acesso (falta de segmentação) ocorreu em seu programa.
- a parte do programa que acontece o erro está em negrito.
- esta função encontra-se em um arquivo diferente do main (.h)

Se alguém puder me ajudar eu agradeço muito.

Obrigado


int cadastro(status *p, int pos)
{
if(pos>CODIGO_MAX)
printf("\nMemoria cheia!\n\n");
else
{
pos = 1;
while(p[pos-1].codigo!='\0')
pos++;
p[pos-1].codigo=(pos+5);
do{
printf("Entre com sua senha (0 a 15): ");
scanf("%d",*(p[pos-1].senha));
if(p[pos-1].senha<0 || p[pos-1].senha>15)
printf("\nSenha invalida\n");
}while(p[pos-1].senha<0 || p[pos-1].senha>15);
}
return pos;
}
bfccardoso
Bit
 
Mensagens: 23
Registrado em: 23 Jan 2007 15:38

Mensagempor bfccardoso » 23 Jan 2009 10:44

na verdade não existe esse * na linha onde ocorre o erro.
no programa a linha se encontra da seguinte forma:

scanf("%d",p[pos-1].senha);

Obrigado!
bfccardoso
Bit
 
Mensagens: 23
Registrado em: 23 Jan 2007 15:38

Mensagempor msamsoniuk » 23 Jan 2009 11:04

pis eh,s em saber o que eh a struct ali fica dificl... senha eh inteiro ou string ? se for inteiro, entao o correto eh:

Código: Selecionar todos
scanf("%d",&p[pos-1].senha);


se for string, o correto eh:

Código: Selecionar todos
scanf("%s",p[pos-1].senha);


isso pq no scanf vc nao diz o q vc quer ler, mas sim o tipo da variavel que vc vai escrever.

ah. e nunca se coloca funcoes em arquivos .h... sempre em arquivos .c. os .h sao para definicoes, typedefs e coisas do genero.
#innovation #poweredby #riscv https://github.com/darklife/darkriscv
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor bfccardoso » 23 Jan 2009 12:35

de fato o arquivo foi salvo como "rotinas.c" mas no arquivo "main.c" eu o chamo como "rotinas.h". abaixo está o código inteiro dos dois arquivos.

main.c

#include <stdio.h>
#include <stdlib.h>
#include "rotinas.h"
#define CODIGO_MAX 4

typedef struct STATUS
{
unsigned int presente : 1;
unsigned int liberado : 1;
unsigned int senha:4;
unsigned int codigo : 2;
}status;

int opcoes (void);
int cadastro(status *p, int pos);

int main(int argc, char *argv[])
{
// struct STATUS teste[CODIGO_MAX];
status teste[CODIGO_MAX];
int cod,s,aux,pos=1;

for(aux=0;aux<CODIGO_MAX;aux++)
teste[aux].codigo = '\0';

for(;;)
{
switch(opcoes())
{
case 1:
{
pos=cadastro(&(teste),pos);
break;
}
case 2:
{
entrada();
break;
}
case 3:
{
saida();
break;
}
case 4:
{
exit(1);
break;
}
default:
{
printf("Opcão invalida!\n\n");
}
}
}
system("PAUSE");
return 0;
}


rotinas.c

#define CODIGO_MAX 4

typedef struct STATUS
{
unsigned int presente : 1;
unsigned int liberado : 1;
unsigned int senha:4;
unsigned int codigo : 2;
}status;

int cadastro(status *p, int pos);
int opcoes (void);
void entrada();
void saida();

int opcoes (void)
{
int aux;
printf("Digite uma das opcoes abaixo\n");
printf("1 - Cadastro\n");
printf("2 - Entrada\n");
printf("3 - Saida\n");
printf("4 - Sair\n");
printf("Opcao: ");
scanf("%d",&aux);
return aux;
}

int cadastro(status *p, int pos)
{
if(pos>CODIGO_MAX)
printf("\nMemoria cheia!\n\n");
else
{
pos = 1;
while(p[pos-1].codigo!='\0')
pos++;
p[pos-1].codigo=(pos+5);
do{
printf("Entre com sua senha (0 a 15): ");
scanf("%d",(p[pos-1].senha));
if(p[pos-1].senha<0 || p[pos-1].senha>15)
printf("\nSenha invalida\n");
}while(p[pos-1].senha<0 || p[pos-1].senha>15);
}
return pos;
}
bfccardoso
Bit
 
Mensagens: 23
Registrado em: 23 Jan 2007 15:38

Mensagempor joao » 23 Jan 2009 12:48

Vc já tentou a solução que o marcelo apresentou?
De colocar um & na linha que está dando erro?

Outra coisa, vc deve ter um arquivo chamado rotinas.h né?

Faça a declaração da struct e defines e também a declaração das funções neste arquivo. Dai vc pode apagar isso do seu rotinas.c e também faz apenas um include do .h no lugar do texto que vc deletou.

Por curiosidade, pq vc tá fazendo isso:
Código: Selecionar todos
while(p[pos-1].codigo!='\0')
pos++;
p[pos-1].codigo=(pos+5);


Não consegui entender apenas olhando o código.

PS: Toda vez que colocar código aqui no forum, selecione ele e clique no botão "code"que existe em cima de onde vc está escrevendo. Dai o php não irá tirar a identação.

[]'s
Avatar do usuário
joao
Byte
 
Mensagens: 463
Registrado em: 17 Out 2006 08:21

Mensagempor bfccardoso » 23 Jan 2009 13:13

Vc já tentou a solução que o marcelo apresentou?
De colocar um & na linha que está dando erro?

sim, já tentei, mas aí o compilador da um erro dizendo que eu não posso ter um endereço de um campo de bit.

Outra coisa, vc deve ter um arquivo chamado rotinas.h né?

na verdade eu tenho um arquivo chamado rotinas.c mas eu o chamo no arquivo main.c desta forma: include "rotinas.h"

Faça a declaração da struct e defines e também a declaração das funções neste arquivo. Dai vc pode apagar isso do seu rotinas.c e também faz apenas um include do .h no lugar do texto que vc deletou.

minha intenção é aprender como fazer um programa simples no main.c e criar vários outros arquivos com as funções que necessito, será que se eu fizer o que você está dizendo vou estar fugindo disso?

Por curiosidade, pq vc tá fazendo isso:
Código:
while(p[pos-1].codigo!='\0')
pos++;
p[pos-1].codigo=(pos+5);

para poder achar a próxima posição vazia do vetor, e assim poder gravar um novo usuário na mesma. quando acho gravo qualquer coisa diferente de '\0', no caso (pos+5). (pura viagem pra dizer a verdade)

Não consegui entender apenas olhando o código.

PS: Toda vez que colocar código aqui no forum, selecione ele e clique no botão "code"que existe em cima de onde vc está escrevendo. Dai o php não irá tirar a identação.

valeu pela dica
bfccardoso
Bit
 
Mensagens: 23
Registrado em: 23 Jan 2007 15:38

Mensagempor bfccardoso » 23 Jan 2009 13:54

é...

se eu paro de trabalhar com bit's tudo funciona perfeitamente.

alguém sabe como eu faço para trabalhar com bit's e usar passagem por referência?

Obrigado!

_____________________________________________________________

O prego que mais se destaca é o primeiro a levar a martelada.
bfccardoso
Bit
 
Mensagens: 23
Registrado em: 23 Jan 2007 15:38

Mensagempor joao » 23 Jan 2009 14:20

Vc pode dar um exemplo de senha?

Porque vc reservou 4 BITS para a senha, mas está pegando um DECIMAL que é 4 BYTEs(32 BITS) no scanf.

Tá vendo porque ele está reclamando?
se vc realmente quer apenas os 4 BITS, eu acho que uma opção é usar um int no seu scanf e dai pegar apenas os 4 primeiros bits...

Bom, fiz um programinha aqui, tentando usar a idéia do seu programa. Tem algumas coisas que eu ainda acho que podem ser mudadas, mas é ao gosto do fregues então nem mexi! :)

main.c
Código: Selecionar todos
#include "rotinas.h"

int main(int argc, char *argv[])
{
   int cod,s,aux,error;
    CADASTRO cadastro[CODIGO_MAX];
   inicializa();

   for(;;)
   {
      switch(opcoes())
      {
         case 1:
            error = novo_cadastro(&cadastro);
            if(error == 1)
               printf("\nMemoria cheia!\n\n");
            else
               printf("\nCadastrado com sucesso!\n\n");
            break;

         case 2:
            entrada();
            break;

         case 3:
            saida();
            break;

         case 4:
            exit(1);
            break;

         default:
            printf("Opcão invalida!\n\n");
      }
   }
   system("PAUSE");
   return 0;
}


rotinas.c
Código: Selecionar todos
#include "rotinas.h"

void inicializa()
{
   //Tudo que precisa ser inicializado, coloca aqui
   posi = 0;
}


int opcoes (void)
{
   int aux;
   printf("Digite uma das opcoes abaixo\n");
   printf("1 - Cadastro\n");
   printf("2 - Entrada\n");
   printf("3 - Saida\n");
   printf("4 - Sair\n");
   printf("Opcao: ");
   scanf("%d",&aux);
   return aux;
}

int novo_cadastro(CADASTRO *p)
{
   if( posi == CODIGO_MAX)
   {
      return 1; //Deu erro! Memoria Cheia!!!
   }
   else
   {
      do
      {
            int i;
         printf("\nEntre com sua senha (0 a 15): ");
         scanf("%b",&i);
         p[posi].senha = i & 0x04; //Pegando apenas os 4 ultimos bits;
         if(p[posi].senha < 0 || p[posi].senha > 15)
         {
            printf("\nSenha invalida\n");
         }
         else
         {
            posi++;
            return 0; //Pegou a senha corretamente e retorna sem erros!
         }
      }while(1);
   }
}

void entrada()
{
    //PARA FAZER
}

void saida()
{
    //PARA FAZER
}


rotinas.h
Código: Selecionar todos
#include <stdio.h>
#include <stdlib.h>

#define CODIGO_MAX 4

typedef struct
{
   unsigned int presente : 1;
   unsigned int liberado : 1;
   unsigned int senha    : 4;
}CADASTRO;

int novo_cadastro(CADASTRO *p);
int opcoes (void);
void entrada();
void saida();
void inicializa();

int posi;


Testei no Dev-Cpp e tá rodando. Mas como eu disse, dá para ser mudado bastante este seu código. Como exemplo o if que vc verifica a senha não precisa pq vc só tem 4 bits, logo ele vai ser entre 0 e 15. Não tem como ser outro valor. Então daria para eliminar.
Também é comum deixar a variavel da estrutura no outro arquivo e não no main. Mas mantive lá para te mostrar passagem de parametros com ponteiros...

[]'s
Avatar do usuário
joao
Byte
 
Mensagens: 463
Registrado em: 17 Out 2006 08:21

Mensagempor bfccardoso » 23 Jan 2009 15:15

joao,

valeu cara, fico te devendo essa!

comecei a estudar C na segunda-feira desta semana, já tinha visto antes mas muito pouco, e como vou ter que trabalhar profissionalmente com ele agora fazendo softwares embarcados, peguei o livro C Completo e Total e não estudo menos 10 horas por dia.

Como as memórias dos microcontroladores não são grande coisa, tenho que trabalhar muito com bit's.

Obrigado mais uma vez!

Abraços.
bfccardoso
Bit
 
Mensagens: 23
Registrado em: 23 Jan 2007 15:38

Mensagempor joao » 23 Jan 2009 15:30

Ola bfccardoso,

É claro que é importante vc trabalhar com bits!

mas realmente eu acho que vc deveria primeiro trabalhar com o código em si, pois como vc viu, é bem simples usar os bits.

Te aconselho a pegar algum código de alguma coisa já implementada e trabalhar com ele, por exemplo, mudar cor, frases e etc, para entender o jeito do C.

Tente ver nestes exemplos como se usa vários arquivos, como se consegue compartilhar a variável e etc...

Depois veja algumas coisas mais chatas de aprender, como bits, structs, unions, static variables, void *(ponteiros do tipo void) e etc...

Mas parabéns pela dedicação!

Aproveita e vai perguntando o que precisa que o pessoal vai ajudando no que puder...

[]'s
Avatar do usuário
joao
Byte
 
Mensagens: 463
Registrado em: 17 Out 2006 08:21

Mensagempor msamsoniuk » 23 Jan 2009 16:25

bfccardoso escreveu:Vc já tentou a solução que o marcelo apresentou?
De colocar um & na linha que está dando erro?

sim, já tentei, mas aí o compilador da um erro dizendo que eu não posso ter um endereço de um campo de bit.



para vc ver neh, ninguem iria adivinhar que era um bitfield se vc nao colasse o codigo inteiro... mas dae nao dah mesmo, pq o scanf com parametro %d requer um ponteiro para inteiro!

receba numa variavel temporaria e depois copie para o campo:

Código: Selecionar todos
int lalala;
scanf("%d",&lalala);
valor.bitfield_doido = lalala;
#innovation #poweredby #riscv https://github.com/darklife/darkriscv
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor msamsoniuk » 23 Jan 2009 16:35

o bom eh estudar pelo K&R segunda edicao (padrao ANSI)...

todo mundo que eu vi aprender pelo "C completo e total" me parece escrever um codigo ruinzinho (nunca tive curiosidade de ver o livro, mas pelo jeito eh ruim). quem eu vi aprender pelo K&R geralmente escreve um codigo melhor. o K&R eh antigao, vc encontra em qq biblioteca... e ateh em pdf se vc procurar bem.

bfccardoso escreveu:joao,

valeu cara, fico te devendo essa!

comecei a estudar C na segunda-feira desta semana, já tinha visto antes mas muito pouco, e como vou ter que trabalhar profissionalmente com ele agora fazendo softwares embarcados, peguei o livro C Completo e Total e não estudo menos 10 horas por dia.

Como as memórias dos microcontroladores não são grande coisa, tenho que trabalhar muito com bit's.

Obrigado mais uma vez!

Abraços.
#innovation #poweredby #riscv https://github.com/darklife/darkriscv
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor chrdcv » 23 Jan 2009 22:32

Valiosas contribuições também podem ser encontradas em:
http://www.ioccc.org/ o qual recomendo que diariamente abra um código fonte e faça algumas verificações!

christian
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13


Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x