Ir para conteúdo
Fórum Script Brasil
  • 0

Desafio aos programadores avanacados C++


krad99

Pergunta

Segue o codigo abaixo instavel, ninguém sabe por que, 3 professores da minha faculdade olharam e não sabem por que se alguém conseguir resolver eu vou fik bastante agredecido.funciona e não funciona...ou seja funciona quando quer...esse programa parte do principio q um aviao sai de recife e vai para algum canto...porem você deve cadastrar um passageiro e uma poltrona mas antes de inserir alguém na poltrona você deve checar se a poltrona já esta ocupada...logo quando eu coloco um if para o resultado da poltrona isso quando pega por q as vezes ele nem roda[abre e fecha]...enfim já tentei de tdo mas não consigo nada =p...totamente instavel o programa...

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define tagpoa "<poltrona>"
#define tagpof "</poltrona>"
#define tagpaa "<passageiro>"
#define tagpaf "</passageiro>"
int continuar;

int flag;

FILE *parquivo; //ponteiro para arquivo
void abre_arquivo()
{ if ((parquivo = fopen("aviao.txt","r+b"))== NULL)
parquivo = fopen("aviao.txt","w+b");
}
int procura(char p[20]){
int i,x;
char textoArquivo[100];
char linha;
char val[10];
char poltrona[2];
char aux[1];
char aux2[2];
x = 10;
for(i = 0; !feof(parquivo);i++){ //incrementa 'i' enquando não for
fgets(textoArquivo, 101, parquivo); //pega uma string de 100 caracteres

while(textoArquivo[x] != '<'){
fflush(stdin);
aux[1] = textoArquivo[x];
strcat(poltrona,aux);
strcat(aux2,poltrona);
++x;


}

if(strstr(aux2,p)){
return 1;

}
continue; //volta ao inicio do loop sem executar o resto
}

return 0;
}


void cadastrar(){
int ie;
char entrada[30];
char entrada2[30];
printf("\n Cadastrar Novo Aluno\n\n");
printf("\n\tNome do Aluno.....: ");
gets(entrada);
printf("\n\tNome do Aluno.....: ");
gets(entrada2);
ie = procura(entrada2);
printf("%d",ie);

char aux_tagpoa[60] = tagpoa;
char aux_tagpaa[60] = tagpaa;
strcat(aux_tagpoa,entrada2);
strcat(aux_tagpaa,entrada);
strcat(aux_tagpoa,aux_tagpaa);
strcat(aux_tagpoa,tagpaf);
strcat(aux_tagpoa,tagpof);
char *xml = aux_tagpoa;
printf("%-20s",xml);
fseek(parquivo,0,SEEK_END);
fwrite(xml,strlen(xml),1, parquivo);
getch();}




main(){
abre_arquivo();
cadastrar();
getch();
}[/codebox]

Link para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

  • 0

Inicialmente eu queria fazer uma pergunta: professores de linguagem C viram este programa e não viram nada de errado? Tem muita coisa errada, além de que ele nem funciona! Quem está aprendendo é normal mas professores não encontrarem nada de errado é que ficou feio! De qualquer forma vou responder, sem problemas... :)

O sintoma que você descreve é causado quando há violação no acesso à memória. Assim, em uma situação dessas, você deve checar se os seus vetores e ponteiros estão acessando áreas reservadas para eles ou se estão ultrapassando os limites.

Existem vários pontos no programa em que violações estão ocorrendo. Seguem abaixo meus comentários:

1) abre_arquivo

void abre_arquivo()
{
  if ((parquivo = fopen("aviao.txt","r+b"))== NULL)
     parquivo = fopen("aviao.txt","w+b");
}
Esta função abre o arquivo sem criá-lo e, caso ele não exista, abre novamente para que ele seja criado. Aqui existe um problema: se você rodar o programa em um disco em modo de somente-leitura como um CD, por exemplo, o arquivo não será criado e o programa não checa isso, causando um erro no programa ao tentar ler o arquivo. 2) procura
int procura(char p[20])
{
  int i,x;
  char textoArquivo[100];
  char linha;
  char val[10];
  char poltrona[2];
  char aux[1];
  char aux2[2];
  x = 10;

  for(i = 0; !feof(parquivo);i++) { //incrementa 'i' enquando não for
     fgets(textoArquivo, 101, parquivo); //pega uma string de 100 caracteres

     while(textoArquivo[x] != '<') {
        fflush(stdin);
        aux[1] = textoArquivo[x];
        strcat(poltrona,aux);
        strcat(aux2,poltrona);
        ++x;
     }

     if(strstr(aux2,p)){
        return 1;
     }

     continue; //volta ao inicio do loop sem executar o resto
  }

  return 0;
}
Aqui existem alguns problemas: a) O contador i não é utilizado em lugar algum! Ele é desnecessário e pode ser removido. Assim podemos transformar o for em um while com a condição e desprezando a inicialização e incremento do for. b ) A função fgets irá receber 101 caracteres porém a variável só pode armazenar 100 caracteres! A chamada a esta função com estes parâmetros irá causar violação no acesso à memória. c) Em while(textoArquivo[x] != '<') você está buscando por '<' dentro de textoArquivo, correto? Como x começa com 10, a busca iniciará na posição 11 (o vetor começa em zero!). Isto está correto? Acredito que deveria começar em 0. d) O comando fflush(stdin) serve para descarregar o que estiver no buffer de entrada, ou seja, algo que tenha sido digitado pelo usuário. Neste momento, porém, não é lido nenhum dado de usuários e portanto essa chamada é desnecessária, podendo ser removida. e) Em aux[1] = textoArquivo[x] você está inserindo um dado de textoArquivo na segunda posição de aux porém a sua declaração indica que este é um vetor de apenas uma posição! Neste ponto também está ocorrendo violação no acesso à memória f) A função strcat serve para concatenar strings, ou seja, adicionar uma no final da outra. Em C o byte nulo (valor zero) indica o fim de uma string e portanto ambas as strings devem obrigatoriamente possuir bytes nulos marcando seu final. Porém, aux, poltrona e aux2 não o possuem! Além disso o maior vetor possui 2 posições! Estes strcat são dos comandos que mais estão violando o acesso à memória neste programa. g) A instrução continue não tem qualquer efeito e pode ser removida. 3) cadastrar
void cadastrar()
{
  int ie;
  char entrada[30];
  char entrada2[30];

  printf("\n Cadastrar Novo Aluno\n\n");
  printf("\n\tNome do Aluno.....: ");
  gets(entrada);
  printf("\n\tNome do Aluno.....: ");
  gets(entrada2);
  ie = procura(entrada2);
  printf("%d",ie);

  char aux_tagpoa[60] = tagpoa;
  char aux_tagpaa[60] = tagpaa;
  strcat(aux_tagpoa,entrada2);
  strcat(aux_tagpaa,entrada);
  strcat(aux_tagpoa,aux_tagpaa);
  strcat(aux_tagpoa,tagpaf);
  strcat(aux_tagpoa,tagpof);
  char *xml = aux_tagpoa;
  printf("%-20s",xml);
  fseek(parquivo,0,SEEK_END);
  fwrite(xml,strlen(xml),1, parquivo);
  getch();
}
a) Os textos dos printf devem ter vindo de outro programa e o nome das variáveis não ajudam! Pelo que pude perceber entrada contém o passageiro e entrada2 contém a poltrona. Estou correto? b ) Não use a função gets! Até mesmo alguns compiladores avisam ao utilizá-la pois ela gera um grande problema: não há verificação de limite de vetor e portanto ele é facilmente ultrapassado. Utilize fgets em seu lugar! c) A função procura é executada porém seu resultado apenas é exibido na tela. O programa não checa o retorno e portanto os dados sempre são gravados, independentemente de já existirem no arquivo ou não. Além disso deveria ser buscada a tag formada e não apenas o texto digitado em entrada2 pois assim estaremos comparando qualquer coisa! d) Acredito que o getch não seja necessário neste ponto. 4) main
main()
{
  abre_arquivo();
  cadastrar();
  getch();
}
a) Eu colocaria o tipo de retorno de main como int para não ficar implícito b ) Faltou o fclose para fechar o arquivo c) Adicione um return 0; no final pois main precisa retornar um int! Além do que já falei, o vetor entrada2 é criado com 30 posições mas a função p recebe como argumento um vetor de apenas 20 posições! Ao receber vetores em funções, omita o tamanho para que ele seja escolhido automaticamente. Bem, acho que é isso! :) Segue abaixo o código com as correções:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define TAG_PO_ABRE   "<poltrona>"
#define TAG_PO_FECHA "</poltrona>"
#define TAG_PA_ABRE   "<passageiro>"
#define TAG_PO_FECHA "</passageiro>"

FILE *parquivo; //ponteiro para arquivo
void abre_arquivo()
{
  if ((parquivo = fopen("aviao.txt","r+b")) == NULL)
    if((parquivo = fopen("aviao.txt","w+b")) == NULL) {
      printf("Erro abrindo arquivo!\n");
      exit(1);
    }
}

int procura(char p[])
{
  long tamArquivo, pos;
  char *textoArquivo;
  char poltrona[2];
  char aux[1];
  char aux2[2];

  fseek(parquivo,0,SEEK_END);
  tamArquivo = ftell(stream);
  rewind(parquivo);

  textoArquivo = (char *)(malloc(tamArquivo)); // Aloca espaço para ler o arquivo inteiro
  if(textoArquivo == NULL) {
    printf("Memoria insuficiente!\n");
    fclose(parquivo);
    exit(2);
  }

  fgets(textoArquivo, tamArquivo), parquivo); // Lê o arquivo inteiro

  pos = 0; // Inicializa pos para o loop.
  while(pos<tamArquivo) {
    // Busca início da tag
    while(textoArquivo[pos] != '<') {
      pos++;
      if(pos == tamArquivo) {
        free(textoArquivo);
        return 0;
      }
    }

    if(textoArquivo[pos+1] != '/') { // Achou tag de abertura
      if(!strncmp(textoArquivo+pos, p, strlen(p))) { // Achou poltrona, retorna.
        free(textoArquivo);
        return 1;
      } else { // Poltrona não encontrada, avança para a próxima posição.
        pos++;
      }
    }
  }

  free(textoArquivo);

  return 0;
}

void cadastrar()
{
  int ie;
  char passageiro[30];
  char poltrona[30];

  printf("\n Cadastrar Passageiro\n\n");
  printf("\n\tNome do Passageiro.....: ");
  fgets(passageiro, sizeof(passageiro), stdin);
  printf("\n\tPoltrona...............: ");
  fgets(poltrona, sizeof(poltrona), stdin);

  // Força o nulo no final
  passageiro[sizeof(passageiro)-1] = 0;
  poltrona  [sizeof(poltrona  )-1] = 0;

  } else {
    char aux_tags[120] = TAG_PO_ABRE;
    char *xml;

    strcat(aux_tags, poltrona);
    if(procura(aux_tags)) { // Busca tag de poltrona fornecida por usuário
      printf("Assento ocupado!\n");
    } else {
      strcat(aux_tags, TAG_PA_ABRE);
      strcat(aux_tags, passageiro);
      strcat(aux_tags, TAG_PA_FECHA);
      strcat(aux_tags, TAG_PO_FECHA);

      xml = aux_tags;
      printf("%-20s",xml);

      fseek(parquivo,0,SEEK_END);
      fwrite(xml,strlen(xml),1, parquivo);
    }
  }
}

int main()
{
  abre_arquivo();
  cadastrar();
  fclose(parquivo);
  getch();

  return 0;
}

Obs.: eu não compilei este código, apenas digitei diretamente aqui na resposta do fórum! Teste e, caso exista algum problema, me avise!

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...