Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
fo_11

duvida ler ficheiro

Recommended Posts

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");
}

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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'...

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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;
}

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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:

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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:

Share this post


Link to post
Share on other sites
Localhost

Não? Então experimenta isto:

int i = 0;
while(++i < 10) {
  printf("%i\n", i);
}


here since 2009

Share this post


Link to post
Share on other 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:

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
Sign in to follow this  

×

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.