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

waza

[Resolvido] Duvida com alterações em ficheiros

Mensagens Recomendadas

waza    1
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


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1140
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


Link para a mensagem
Partilhar noutros sites
pmg    96
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
pmg    96
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1140
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1140
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
pmg    96
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1140
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1140
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


Link para a mensagem
Partilhar noutros sites
waza    1
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


Link para a mensagem
Partilhar noutros sites
pmg    96
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


Link 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.