Ir para o conteúdo
salinhux

Apagar Registo

Mensagens Recomendadas

salinhux    0
salinhux

Boas, estou tentando criar uma função que apague registo de clientes, mas não estou a conseguir, quando executo a função ele apaga todos os registos.  :wallbash:

void remover()
{
    FILE *fp,*ft;
    fp = fopen ("clientes.dat", "rb+");
    if(fp==NULL)
    {
        fp=fopen("clientes.dat", "w+");
        fclose(fp);
        fp=fopen("clientes.dat", "r+");

    }

    recsize=sizeof(P);
     printf("%d",recsize);
    printf("Nome: ");
    gets(P[i].sNome);
    ft=fopen("temporario.dat","wb");
    rewind(fp);

    while(fread(&P,recsize,1,fp)==1)
    {

        if( strcmp(P[i].sNome,P[i].sMorada)!=0)
            fwrite(&P,recsize,1,ft);

    }
    fclose(fp);
    fclose(ft);
    remove("clientes.dat");
    rename("temporario.dat","clientes.dat");
    fp=fopen("clientes.dat","rb");
}

Se alguém poder dar uma vista de olhos agradecia :(

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
pmg    102
pmg

Deixa de usar variáveis globais. Ajuda-te a ti e ao programador que vier a seguir, nem que esse programador sejas tu próprio daqui a 6 meses.

O que é P? O que é i? O que é recsize?

Não uses gets(). Essa função é impossível de ser usada com segurança e há substituto perfeitamente razoável: fgets() (possivelmente depois da remoção do '\n' final).

Aparentemente (não posso ter a certeza sem ver mais código) o teu problema prende-se com o recsize. Parece-me que o valor é grande demais para o que tu queres: é o tamanho dum array quando tu queres o tamanho dum elemento.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
salinhux    0
salinhux

Boas sim provavelmente está confuso, sou ainda um novato em C. Vou colocar o código todo, para avaliarem.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

struct clientes
{
    int cod_cliente;
    char sNome[80];
    char sMorada[80];
    int iCodigoPostal;
    int iDatadeNasc;
    int iTelemovel;
    int iNumContribu;
    int iNumBI;
    int iPass;


};
long int recsize;
int cod_cliente;
int indice_cliente;
int quant,carregados;
int saldo = 1000;
int cod;
int i;
int tent;
struct clientes P[10];
int main()
{
    indice_cliente =0;
    char mostramenu();
    inserirclientes();
    remover();
    listagem();
    users();


    while(cod)
    {
        users();

    }
    char ch='0';
    while (ch!='5')
    {
        ch=mostramenu();
        switch(ch)
        {
        case '1':
            levantamentos();
            break;
        case '2':
            consulta();
            break;
        case '5':
            ch='5';
            break;
        default:
            printf("Escolha uma opção válida:1,2 ou 3");
            break;
        }
    }
}




char mostramenu ()
{
    printf("\n\n------ MENU PRINCIPAL ------\n\n");
    printf("1 - Levantamentos\n\n");
    printf("2 - Consultas de saldo\n\n");
    printf("3 - Consultas de movimentos\n\n");
    printf("4 - Transferências\n\n");
    printf("5 - Sair\n\n");
    char c = getch();
    return (c);
}
void levantamentos()
{



    int mont;

    int opclevant = '0';
    printf("|-----Levantamentos-----|\n\n");
    printf("1- 20 Euros\n\n");
    printf("2- 40 Euros\n\n");
    printf("3- 60 Euros\n\n");
    printf("4- 100 Euros\n\n");
    printf("5- 150 Euros\n\n");
    printf("6- 200 Euros\n\n");
    printf("7- Outras importancias\n\n");
    printf("8- Voltar Menu principal\n\n");

    while (opclevant!='8')
    {
        char opclevant = getch();

        switch(opclevant)
        {

        case '1':
            printf("|-------------------------|\n\n");
            printf("Deseja receber recibo?\n\n");
            printf("1-Sim\n");
            printf("2-Nao\n\n");
            char opclevant = getch();
            switch(opclevant)
            {
            case '1':
                mont = 20;
                saldo = saldo-mont;
                printf("Levantou 20 euros\n\n");
                printf("O seu saldo actual e de: %d euros\n\n\n", saldo);
                break;
            case '2':
                mont = 20;
                saldo = saldo-mont;
                break;
            }
            break;
        case '2':
            printf("|-------------------------|\n\n");
            printf("Deseja receber recibo?\n\n");
            printf("1-Sim\n");
            printf("2-Nao\n\n");
            opclevant = getch();
            switch(opclevant)
            {
            case '1':
                mont = 40;
                saldo = saldo-mont;
                printf("Levantou 40 euros\n\n");
                printf("O seu saldo actual e de: %d euros\n\n\n", saldo);
                break;
            case '2':
                mont = 40;
                saldo = saldo-mont;
                break;
            }
            break;
        case '3':
            printf("|-------------------------|\n\n");
            printf("Deseja receber recibo?\n\n");
            printf("1-Sim\n");
            printf("2-Nao\n\n");
            opclevant = getch();
            switch(opclevant)
            {
            case '1':
                mont = 60;
                saldo = saldo-mont;
                printf("Levantaste 60 euros\n\n");
                printf("O seu saldo actual e de: %d euros\n\n\n", saldo);
                break;
            case '2':
                mont = 60;
                saldo = saldo-mont;
                break;
            }
            break;
        case '4':
            printf("|-------------------------|\n\n");
            printf("Deseja receber recibo?\n\n");
            printf("1-Sim\n");
            printf("2-Nao\n\n");
            opclevant = getch();
            switch(opclevant)
            {
            case '1':
                mont = 100;
                saldo = saldo-mont;
                printf("Levantou 100 euros\n\n");
                printf("O seu saldo actual e de: %d euros\n\n\n", saldo);
                break;
            case '2':
                mont = 100;
                saldo = saldo-mont;
                break;
            }
            break;
        case '5':
            printf("|-------------------------|\n\n");
            printf("Deseja receber recibo?\n\n");
            printf("1-Sim\n");
            printf("2-Nao\n\n");
            opclevant = getch();
            switch(opclevant)
            {
            case '1':
                mont = 150;
                saldo = saldo-mont;
                printf("Levantou 150 euros\n\n");
                printf("O seu saldo actual e de: %d euros\n\n\n", saldo);
                break;
            case '2':
                mont = 150;
                saldo = saldo-mont;
                break;
            }
            break;
        case '6':
            printf("|-------------------------|\n\n");
            printf("Deseja receber recibo?\n\n");
            printf("1-Sim\n");
            printf("2-Nao\n\n");
            opclevant = getch();
            switch(opclevant)
            {
            case '1':
                mont = 200;
                saldo = saldo-mont;
                printf("Levantou 200 euros\n\n");
                printf("O seu saldo actual e de: %d euros\n\n\n", saldo);
                break;
            case '2':
                mont = 200;
                saldo = saldo-mont;
                break;
            }
            break;
        case '7':
            printf("|-------------------------|\n\n");
            printf("Deseja receber recibo?\n\n");
            printf("1-Sim\n");
            printf("2-Nao\n\n");
            opclevant = getch();
            switch(opclevant)
            {
            case '1':
                printf("Montante a Levantar:\n");
                scanf("%d", &mont);
                if (mont==5)
                {
                    printf("Limite minimo e de 10 euros");
                }
                else if((mont % 5) == 0)
                {
                    saldo = saldo-mont;
                    printf("\nLevantou %d euros\n\n",mont);
                    printf("O seu saldo actual e de: %d euros\n\n\n", saldo);
                }
                else
                {
                    printf("So existem notas de 5, 10, 20, 50, 100 e 200");
                }

                break;
            case '2':
                printf("Montante a Levantar:\n");
                scanf("%d", &mont);
                if (mont==5)
                {
                    printf("Limite minimo e de 10 euros");
                }
                else if((mont % 5) == 0)
                {
                    saldo = saldo-mont;
                    printf("\nLevantou %d euros\n\n",mont);
                }
                else
                {
                    printf("So existem notas de 5, 10, 20, 50, 100 e 200");
                }

                break;


                break;
            }
            break;
        case '8':
            mostramenu();
            break;
        }
        return (opclevant);
    }

}

void consulta()
{
    printf("O seu saldo actual e de: %d euros\n\n", saldo);
}

int listagem()
{
//printf("%d\n",P[i].iPass);
//printf("\n\nPass: %d\nNome: %s\nMorada: %s\nBI: %d\nData de Nascimento: %d\nTelemovel: %d\nID: %d\n\n",P[i].iPass,P[i].sNome,P[i].sMorada,P[i].iNumBI,P[i].iDatadeNasc,P[i].iTelemovel,P[i].cod_cliente);

    FILE *fp;
    fp = fopen ("clientes.dat", "rb+");
    struct clientes P;
    int fim=0;

    while (!fim)
    {
        fread(&P, sizeof(struct clientes), 1, fp);
        if (feof(fp)) fim=1;
        else
        {
            printf("\n\nPass: %d\nNome: %s\nMorada: %s\n\n",P.iPass,P.sNome,P.sMorada);
        }
    }
    fclose(fp);
}

int inserirclientes ()
{

    FILE *fp;
    fp=fopen("clientes.dat", "rb+");
    if(fp==NULL)
    {
        fp=fopen("clientes.dat", "w+");
        fclose(fp);
        fp=fopen("clientes.dat", "r+");

    }
    printf("Nome:");
    gets(P[i].sNome);
    printf("\nMorada:");
    gets(P[i].sMorada);
    /*printf("\nData de Nascimento:");
    scanf("%d", &P.iDatadeNasc);
    printf("\nTelemovel:");
    scanf("%d", &P.iTelemovel);
    printf("\nNumero Cartão de cidadão:");
    scanf("%d", &P.iNumBI);
    printf("\nNumero Contribuinte:");
    scanf("%d", &P.iNumContribu);
    */

    srand( time(NULL) );
    int pass = rand() % 9000 + 1000;
    P[i].iPass = pass;
    indice_cliente = indice_cliente +1;
    fseek(fp,0,SEEK_END);
    fwrite(&P, sizeof(struct clientes),1,fp);
    fseek(fp,0,SEEK_SET);


}
void remover()
{
    FILE *fp,*ft;
    fp = fopen ("clientes.dat", "rb+");
    if(fp==NULL)
    {
        fp=fopen("clientes.dat", "w+");
        fclose(fp);
        fp=fopen("clientes.dat", "r+");

    }

    recsize=sizeof(P);
     printf("%d",recsize);
    printf("Nome: ");
    gets(P[i].sNome);
    ft=fopen("temporario.dat","wb");
    rewind(fp);

    while(fread(&P,recsize,1,fp)==1)
    {
        if( strcmp(P[i].sNome,P[i].sMorada)!=0)
            fwrite(&P,recsize,1,ft);

    }
    fclose(fp);
    fclose(ft);
    remove("clientes.dat");
    rename("temporario.dat","clientes.dat");
    fp=fopen("clientes.dat","rb");
}
int users()
{


    printf("|----Multibanco----|\n");
    printf("Introuza o seu Codigo:");
    scanf("%d", &cod);
    tent++;
    if(P[i].iPass == cod) //cod == cod1 || cod == cod2
    {
        tent=0;
        cod=0;

    }

    switch(tent)
    {
    case 1:
        printf("Codigo errado! tem mais 2 tentativas!\n");
        break;
    case 2:
        printf("Codigo errado! Tem apenas mais uma tentativa!\n");
        break;
    case 3:
        printf("Codigo errado! Excedeu o limite de tentativas!\n");
        exit(1);
        break;

    }

    return(cod);
}

O programa é uma simulação de uma caixa multibanco, tem utilizadores onde ao registar gere uma password onde serve de código para entrar.

No entanto as funções estão logo antes do menu, fiz assim agora para ir testando.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
pmg    102
pmg

Xiiiiiiiiii ... aumenta o nivel de warnings do teu compilador e compoe o código até ele deixar de dar warnings.

A forma usual de declarar / definir / usar funções (sem #includes ou outros ficheiros .c) é:

declaras a função a nível global, depois das definições de tipos dados mas antes das definições das funções propriamente ditas;

a definição da função pode ser feita antes ou depois da função main.

Tu tens as funções declaradas dentro da função main: passa a declaração para fora.

O uso de variáveis globais pode parecer que facilita a programação, mas é um parecer falso. As variáveis globais atrapalham mais do que ajudam.

Passa a definição das variáveis globais para dentro da função main (e inicializa-as), altera as funções para receberem parametros, e passa os valores ou enedereços das variaveis para as funcoes.

Mete labels default nos teus switches.

A inicialização do gerador de números aleatórios (o srand(time(NULL))) só deve ser executada uma vez de cada vez que executas o teu programa. Como a tens dentro duma função está a reduzir a eficácia do gerador. Tira essa instrução de dentro da função inserirclientes() e passa-a para uma das primeiras instruções da função main().


Confirmo que o teu problema que origina o apagamento de todos os registos é do recsize na função remover() ser grande demais.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

Eu vou voltar a refazer a minha crítica:

fp = fopen ("clientes.dat", "rb+");
if(fp==NULL)
{
    fp=fopen("clientes.dat", "w+");
    fclose(fp);
    fp=fopen("clientes.dat", "r+");

}

Traduzindo para português:

Abre um ficheiro binário para leitura e escrita.

Se não for possível abrir o ficheiro:

Cria um ficheiro ou abre e limpa o ficheiro para leitura e escrita.

Fecha o ficheiro.

Abre o ficheiro existente para leitura e escrita.

No final, aquilo que queres sempre é acesso a um ficheiro para leitura e escrita. Estás apenas a repetir o processo duas vezes não sei bem com que objectivo.

Depois, tens uma confusão de coisas no teu for de leitura/escrita, entre elas uma comparação do nome com uma morada, não se percebe bem porquê. Tu tens que ler o cliente do ficheiro para uma estrutura que até podes alocar dentro da função só para isso, depois comparas o nome que o utilizador inseriu com o nome do cliente que acabaste de ler e se forem diferentes inseres no novo ficheiro.

E no final fechas tudo e voltas a abrir o ficheiro logo antes do fim da função, que é mais uma coisa que não se percebe porquê.

Depois, podes enviar parametros para as funções. Em todas as funções que estou a ver no teu código não existe uma que receba parametros. A título de exemplo, a tua função remover() pode receber o parametro para o array de clientes da seguinte forma:

void remover(struct clientes* P);

Embora isto nem seja necessário, porque estás a ler os clientes directamente do ficheiro, que, como disse anteriormente, só necessitam de uma alocação dentro da própria função.

Para além disso, nomes de variáveis devem ser declaradas com letra minúscula, logo o teu P, devia ser p. E deves ser mais descritivo em relação aos nomes das tuas variáveis. Se alguns anos depois te lembrares que tinhas um pedaço de código que fazia qualquer coisa que vais precisar e fores ver esse código, teres nomes deste tipo só te dificultam a leitura do código (que mal te deverás lembrar nessa altura).

De qualquer forma, como disse o pmg, tens muito por onde corrigir. E devias pensar nisto de outra forma. Por exemplo, a função remover devia ser feita de forma a que se recebesse o parametro que identifica o cliente a remover e não a pedir ao utilizador para indicar que cliente pretende remover. Isso farias externamente.

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