Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

fo_11

duvida ler ficheiro

Mensagens Recomendadas

fo_11

Porque é que se tem de colocar v(contador-1)='\0' e não se pode usar v(contador)='\0' visto que o realloc criou um vecto um tamanho igual ao contador?

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

int main()
{
    char *str=NULL,nome[20],ch;
    FILE *fp;
    int contador=0;
    printf("Nome ficheiro:");
    gets(nome);
    
    if((fp=fopen(nome,"r"))==NULL)
     printf("Nao foi possivel aceder ao ficheiro");
    
    while((ch=fgetc(fp))!=EOF)
      {str=(char*)realloc(str,(++contador)*sizeof(char));
       str[contador-1]=ch;
      }
      str[contador-1]='\0';//o problema está aqui!!!!!!!!!!
         
    puts(str); 
    free(str);  
    system("pause");
}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Porque estás a fazer isto:

++contador

Ou seja, ele vai primeiro incrementar. Se fizesses:

contador++

Já não era preciso colocar o -1


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
fo_11

mas o objectivo é esse... primeiro incrementar e depois aumentar devidamente a string. Eu tenh o contador inicializado a 0 se colocar contador++ o compilador dará erro... E se a string tem o tamanho do contador logo deveria dar com v[contador]='\0'...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Se a string tem o tamanho do contador então para indexares a última posição da mesma tens de fazer str[cont - 1] porque começa sempre em 0.

p.s. O código que mostraste está a dar erro ou não percebes o porquê do -1?


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
fo_11

não percebo a razao do -1

aqui está um outro programa mas já não ocorre esse problema

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

int Ocorrencias(char*,int,char);

int main()
{
    char *str=NULL,nome[20],ch;
    FILE *fp;
    int contador=0;
    printf("Nome ficheiro:");
    gets(nome);
    
    if((fp=fopen(nome,"r"))==NULL)
     printf("Nao foi possivel aceder ao ficheiro");
    
    while((ch=fgetc(fp))!=EOF)
      {str=(char*)realloc(str,(++contador)*sizeof(char));
       str[contador-1]=ch;
      }
      str[contador]='\0';\\é aqui que está a diferenaça e funciona mt bem
    printf("Qual é o caracter a contar dentro da string:");
    scanf(" %c",&ch);
    
    
    puts(str);   
    printf("\nOcorrencias:%d",Ocorrencias(str,contador,ch));
    system("pause");
}


int Ocorrencias(char *str,int dim,char ch)
{
    int contador=0,i;
    for(i=0;i<=dim;i++)
     {if(str[i]==ch)
       contador++;
     }
    return contador;
}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

Tu ao fazer ++contador é como se começasses o while com 1 e não com 0. Ou seja, no final ele vai ter +1 posições do que a real. Entendes? Daí teres de fazer -1.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cynary

O que estás a fazer mal é aceder memória não alocada, não podes fazer isso ...

É assim, ao alocares contador de memória (já que é incrementada primeiro a variável, então o valor com que contador fica depois da alocação, é o valor alocado), estás a colocar o último caracter na posição contador-1 do array.

Por exemplo, imagina que alocas 2 caraceteres, podes ocupar a posição 0 e 1 do array. Assim, a posição 2-1 é a última a ser ocupada.

Presumo que queiras sempre colocar um novo caracter no fim da string, e para isso estás a mudar o tamanho dela.

Para isso, a primeira string tem de ter pelo menos dois caracteres (o que queres colocar e o terminador). Ou isso, ou põe o \0 depois de colocares os caracteres.

Se decidires estar sempre a mudar os caracteres, e tens de começar com 2, então tens de alterar o código assim:

  int contador = 1
...
    str[contador-2] = ch
    str[contador-1] = '\0';
  }
...

É contador-2, porque, usando o exemplo anterior, se tivesses dois caracteres na string, querias o terminador ('\0') na posição 1 e o caracter na posição 0.

Se quiseres apenas colocar o caracter terminador no final (que é +- o que estavas a tentar fazer), então o novo caracter fica sempre na posição contador-1, depois incrementas o contador, realocas a memória e colocas o '\0' (faltou-te incrementar, por isso sobrepunhas o último caracter):

...
  }
  str=(char *) realloc(str, (++contador)*sizeof(char));
  str[contador-1] = '\0';

Localhost: o problema não é isso ... o problema está no facto de os índices começarem em 0, logo ele vai ter sempre contador-1 posições na array.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost
Localhost: o problema não é isso ... o problema está no facto de os índices começarem em 0, logo ele vai ter sempre contador-1 posições na array.

Lol, e o que é que eu disse?

Tu ao fazer ++contador é como se começasses o while com 1 e não com 0. Ou seja, no final ele vai ter +1 posições do que a real. Entendes? Daí teres de fazer -1.


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
fo_11

sim, era mas não tinha percebido bem o que querias dizer por indice mas agora já está tudo esclarecido.

o programa já funciona  :thumbsup:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cynary

Então entendi mal xD

Percebi que estavas a associar o ++ ao ter mais 1 posição do que a real. Se era isso, então está mal, pois não interessa se tinha ++ ou não, o contador corresponde sempre a mais um valor do que as posições totais (à excepção de quando se usa outras excepções, como o ++ depois ou +1,+2, ...).

Se não era isso, então compreendi mal.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
fo_11

Aquilo que percebi é o seguinte:

no while temos o realloc que com a utilizacao do contador faz:

1 -espaco para um caracter,

2-espaco para outro caracter,

3-espaco para outro caracter,

e eu preencho os espaços vazios e para isso temos de fazer:

v[0]-colocar caracter porque temos 1 espaco para um caracter e ele encontra-se na posicao zero do vector

v[1]-colocar caracter

v[2]-colocar caracter e neste caso terminou os espacos

para colocar '\0' preciso de criar mais um espaco para o novo caracter '\0' então:

v=(char*)realloc(v,++contador*sizeof(char));

e vou colocar na sua devida posicao:

v[3]-colocar '\0' e não v[4], 4 que é o numero do contador logo tenh de fazer 4-1 que é 3 :thumbsup:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cynary

Localhost, compreendeste mal o que eu disse que tinha compreendido mal xD

Aí, o while começa com o valor 1 ...

O que eu estou a dizer é que, se utilizasse realloc(contador*sizeof(char)) ou realloc(++contador*sizeof(char)) seria o mesmo, já que o índice a utilizar seria contador-1.

No entanto, se contador fosse 0, aí haveria um problema. Mas senão, era indiferente neste caso se era ++contador ou só contador.

fo_11: Exactamente, compreendeste perfeitamente :thumbsup:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.