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

waza

[Resolvido] Duvida com alterações em ficheiros

Mensagens Recomendadas

waza

Boas pessoal,

eu queria saber como se altera um bloco de informação em ficheiro...

por exemplo, tenho uma estrutura com as informações de alunos e quero alterar o nome do aluno no ficheiro... como posso eu fazer isso?

obrigado ;)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

depende da maneira como tens codificada a informação do aluno no ficheiro

- é um ficheiro binário que guarda as estruturas de forma sequencial como em memória ?

- é um ficheiro de texto onde os registos estão escritos em linhas de texto ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

A maneira básica mais prática é:

1) ler o ficheiro todo para memória

2) alterar o conteúdo da memória

3) reescrever (apagando o original) o ficheiro a partir da memória

Editado por pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

é um ficheiro binario que guarda tudo seguidinho, queres que meta todo o codigo?

sim eu tinha pensado nisso @pmg mas acho que isso sobre-carrega um pouco o programa ou estarei enganado?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

sim eu tinha pensado nisso @pmg mas acho que isso sobre-carrega um pouco o programa ou estarei enganado?

Sim, sobrecarrega (dependendo exactamente do que estas a fazer).

Mas, se o ficheiro tem menos de .... oh, sei lá ... 50Megas, não te preocupes :)


Outra maneira, também básica é abrires o ficheiro original para leitura e outro ficheiro novo para escrita. Depois vais lendo dum, alterando os dados se necessário, e escrevendo no outro. No final apagas o ficheiro original e mudas o nome ao ficheiro novo.

Editado por pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

humm, esta bem, obrigado ;)

eu tenho tentado melhorar os meus codigos, para consumir menos linhas e ser mais objetivo/perceptível a outras pessoas, daí querer uma coisa mais "simples" ! :P

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

eu tinha pensado nisso s:

se carregar apenas o registo que quero, e depois o voltar a enviar para o ficheiro ele ira sobrepor esse bloco ou ira adicionar mais um? é essa a minha duvida tambem !

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

existe ainda uma outra alternativa:

struct Aluno {
 char nome[100];
 // ...
};

// ...

FILE * fd = fopen("file", "a+b");                       // abrir o ficheiro
char * nome = "Nome";                                   // nome a procurar
struct Aluno aluno;                                     // estrutura auxiliar de leitura e alteração

rewind(fd);

while (fread(&aluno, sizeof(struct Aluno), 1, fd)) {    // enquanto ler registos do ficheiro
 if (strcmp(aluno.nome, nome) == 0) {                  // verificar se é o registo pretendido

   // alterações ...

   fseek(SEEK_CUR, - sizeof(struct Aluno));            // mover o ponteiro interno do stream para a posição correcta do registo a alterar
   if (!fwrite(&aluno, sizeof(struct Aluno), 1, fd)) { // escrever/sobrepor o registo
     fprintf(stderr, "Erro de escrita");
   }

   break;                                              // terminar o ciclo
 }
}

fclose(fd);                                             // fechar o stream

// ...

Editado por HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

pronto, ja consegui que alterasse, mas no fim fica tipo: insiro 1 e altero-o e ele passa para o 3 em vez de inserir o aluno 2...

como se insere o code mesmo?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

eu queria saber como se altera um bloco de informação em ficheiro...

pronto, ja consegui que alterasse, mas no fim fica tipo: insiro 1 e altero-o e ele passa para o 3 em vez de inserir o aluno 2...

afinal queres adicionar um registo novo ou alterar um existente ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

talvez nao me tenha explicado bem...

eu insiro um ! depois quero alterar esse registo e ele altera ! até aqui tudo bem

mas quando vou para inserir outro, supostamente sería o aluno 2, ele insere como com o numero 3 !

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

entao, e ha maneira de consertar esse "erro"?

Vou-me por a adivinhar ...

Em vez de usares modo "a+b" usa modo "r+b"

fopen("whatever", "r+b")

:)

Editado por pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

suponho que isto esteja errado xD

fp = fopen("DADOS.dat", "r+b");
	 rewind(stdin);
	 printf("Insira o nome para substituir \"%s\" -> ", ler.nome); fgets(ler.nome, 100, stdin);
	 ler.nome[strlen(ler.nome)-1] = '\0'; // remover o \n do fgets
	 rewind(stdin);
	 fseek(fp, sizeof(aluno)*tell, SEEK_CUR);
 if(fwrite(&ler, sizeof(aluno), 1, fp) != 1)
		 printf("ERRO A ESCREVER\n\n");
 else
		 printf("Nome alterado com sucesso\n\n")

ler é um typedef para a struct

Editado por Rui Carlos
Formatação do código.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

1 - qual o valor da variável "tell" ?

2 - fazer rewind e de seguida um fseek é a mesma coisa que :

//rewind(stdin);
//fseek(fp, sizeof(aluno)*tell, SEEK_CUR);
fseek(fp, sizeof(aluno)*tell, SEEK_SET);


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

desculpa, esqueci-me de por toda a funçao ... aqui esta

if ((fp = fopen("DADOS.dat", "rb")) == NULL)
    printf("Erro ao abrir ficheiro\n");
else
{
    fseek(fp, 0, SEEK_END);
    printf("ALTERAR NOME DE ALUNO... NUMERO DE ALUNOS -> %ld \n\n", ftell(fp) / sizeof(aluno));
    do
    {
        printf("Insira o numero do aluno -> "); scanf("%d", &op);
        rewind(fp);
        fseek(fp, sizeof(aluno)*(op-1), SEEK_SET);
        fread(&ler, sizeof(aluno), 1, fp);
        tell = ftell(fp);
        printf("Escolheu o aluno \"%s\"... continuar? [s/N]", ler.nome );
        rewind(stdin); op2 = getchar();

    }
    while (toupper(op2)!='S');
        fclose(fp);
        fp = fopen("DADOS.dat", "r+b");
        rewind(stdin);
        printf("Insira o nome para substituir \"%s\" -> ", ler.nome); fgets(ler.nome, 100, stdin);
        ler.nome[strlen(ler.nome)-1] = '\0'; // remover o \n do fgets
        rewind(stdin);
        fseek(fp, sizeof(aluno)*tell, SEEK_CUR);
    if(fwrite(&ler, sizeof(aluno), 1, fp) != 1)
            printf("ERRO A ESCREVER\n\n");
    else
            printf("Nome alterado com sucesso\n\n");
}
fclose (fp);

sim, pus o rewind do STDIN a mais, xD

Editado por pmg
GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo
if ((fp = fopen("DADOS.dat", "r+b")) == NULL)
 printf("Erro ao abrir ficheiro\n");
else
{
 fseek(fp, 0, SEEK_END);
 nalunos = ftell(fp) / sizeof(aluno);
 printf("ALTERAR NOME DE ALUNO... NUMERO DE ALUNOS -> %ld \n\n", nalunos);

 do
 {
   printf("Insira o numero do aluno -> ");
   scanf("%d", &op);

   // MUITO IMPORTANTE !!!
   // VALIDAR A SELECÇÃO !!!
   if (op == 0 || op > nalunos) {
     op2 = 'N';
   } else {
     fseek(fp, sizeof(aluno)*(op-1), SEEK_SET);
     fread(&ler, sizeof(aluno), 1, fp);

     printf("Escolheu o aluno \"%s\"... continuar? [s/N]", ler.nome );
     op2 = getchar();
   }
 } while (toupper(op2)!='S');

 printf("Insira o nome para substituir \"%s\" -> ", ler.nome);
 fgets(ler.nome, 100, stdin);
 ler.nome[strlen(ler.nome)-1] = '\0'; // remover o \n do fgets

 fseek(fp, sizeof(aluno) * (op - 1), SEEK_SET);

 if(fwrite(&ler, sizeof(aluno), 1, fp) != 1)
   printf("ERRO A ESCREVER\n\n");
 else
   printf("Nome alterado com sucesso\n\n");

 fclose (fp);
}


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
waza

ahhh, agora ja vi o erro xD

tava dificil... obrigado :P

removes-te uns rewinds que faziam falta porque depois o stdin insere automatico, mas muitoo obrigado :D

ja agora, como fizes-te para o codigo aparecer com cores? xD

Editado por waza

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

ja agora, como fizes-te para o codigo aparecer com cores? xD

Basta escolher a linguagem na tag code (escolher o editor basico, clicando no primeiro botao (que parece um interruptor))

[ code=c]linguagem c[/code ]
[ code=java]linguagem java[/code ]
[ code=vbnet]linguagem Visual Basic Net[/code ]
etc

Editado por pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

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.