-1

I'm writting a program for a car rental system. One of the functionalities should be updating car information in the binary file, but it isn't rewriting it at all. Here's what the struct looks like:

typedef struct {
    int id;
    char placa[8];
    char modelo[10];
    float motor;
    int ar;
    char cor[6];
    int ano;
    int kilo;
    float diaria;
    int dispo;
} Carros;

This is the function that is supposed to update the file, after searching for a specific car (I basically tried to use the same logic from the function that finds specific cars and prints them out.):

void updateCarro() {
    FILE *fp = fopen("Carros.dat", "rb+");
    Carros carro;
    int id, size, cont, regs;
    
    scanf("%d", &id); //variable to find a specific car's ID

//read new information that'll rewrite the old.
    scanf(" %d", &carro.id);
    scanf(" %s", carro.placa);
    scanf(" %s", carro.modelo);
    scanf(" %f", &carro.motor);
    scanf(" %d", &carro.ar)
    scanf(" %s", carro.cor);
    scanf(" %d", &carro.ano);
    scanf(" %d", &carro.kilo);
    scanf(" %f", &carro.diaria);
    scanf(" %d", &carro.dispo);

    if(fseek(fp, 0, SEEK_END) == -1) {
        printf("Erro ao localizar o registro\n");
        return;
    }
    size = ftell(fp);
    if(size == -1) {
        printf("Não há registros\n");
        return;
    }
    if(fseek(fp, 0, SEEK_SET) == -1) {
        printf("Erro ao localizar o registro\n");
        return;
    }
    records = size / sizeof(Carros);
    for(cout = 0; cout < regs; count++) {
        fread(&carro, sizeof(Carros), 1, fp);
        if(carro.id == id) {
            fwrite(&carro, sizeof(Carros), 1, fp);
            break;
        }
    }
}

Here's the function that looks for a car's ID in the binary file and prints all the information. It seems to work, I tested multiple times, but maybe there's a flaw that's relevant. It's probably very easy to tell I'm not very experienced, so any help is welcome.

void mostraCarro() {
    Carros carro;
    FILE *fp = fopen("Carros.dat", "rb");
    int id;
    size_t count, records;
    long size;
    printf("entre com a indentificação do carro: \n");
    scanf("%d", &id);
    if(fseek(fp, 0, SEEK_END) == -1) {
        printf("Erro ao localizar o registro\n");
        return;
    }
    size = ftell(fp);
    if(size == -1) {
        printf("Não há registros\n");
        return;
    }
    if(fseek(fp, 0, SEEK_SET) == -1) {
        printf("Erro ao localizar o registro\n");
        return;
    }
    records = size / sizeof(Carros);
    for(count = 0; count < records; count++) {
        fread(&carro, sizeof(Carros), 1, fp);
        if(carro.id == id) {
            printf("Identificação: %d\n", carro.id);
            printf("Placa: %s\n", carro.placa);
            printf("Modelo: %s\n", carro.modelo);
            printf("Motor: %f\n", carro.motor);
            printf("Ar condicionado: %d\n", carro.ar);
            printf("Cor: %s\n", carro.cor);
            printf("Ano: %d\n", carro.ano);
            printf("Quilometragem: %d\n", carro.kilo);
            printf("Valor da diária: %f\n", carro.diaria);
            printf("Disponibilidade: %d\n", carro.dispo);
            break;
        }
    }
    fclose(fp);
}
  • Questions seeking debugging help should generally provide a [mre] of the problem, which includes a function `main` and all `#include` directives, as well as the exact input required to reproduce the problem. – Andreas Wenzel Jun 27 '22 at 17:24
  • Have you tried running your code line-by-line in a debugger while monitoring the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Jun 27 '22 at 17:26

1 Answers1

1

You're writing the new struct after the one that was read with the matching ID, not in place of it. You need to seek back to the beginning of the record before writing.

    for(count = 0; count < regs; count++) {
        fread(&carro, sizeof(Carros), 1, fp);
        if(carro.id == id) {
            fseek(fp, -(int)sizeof(Carros), SEEK_CUR);
            fwrite(&carro, sizeof(Carros), 1, fp);
            break;
        }
    }

You also need to add fclose(fp); at the end of the function.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Another reason why the additional call to `fseek` is necessary is because in update mode, input shall not be directly followed by output without an intervening call to a file positioning function, unless end-of-file is encountered ([§7.21.5.3 ¶7 of the ISO C11 standard](http://port70.net/~nsz/c/c11/n1570.html#7.21.5.3p7)). Otherwise, the behavior is undefined. This requirement is also mentioned in the documentation for [`fopen`](https://en.cppreference.com/w/c/io/fopen). – Andreas Wenzel Jun 27 '22 at 17:55
  • I knew there was something like that, but I was thinking of the `fflush()` requirement for input after output. – Barmar Jun 27 '22 at 18:00
  • I understand the logic, thanks a lot, but it's now giving me a warning: warning: overflow in conversion from 'long long unsigned int' to 'long int' changes value from '18446744073709551560' to '-56' [-Woverflow] – Raphael Ozono Jun 27 '22 at 18:19
  • I've added a cast. – Barmar Jun 27 '22 at 18:20
  • I tried adding the changes to my code but it didn't seem to work. Thanks a lot for the help though, I really appreciate it – Raphael Ozono Jun 27 '22 at 18:44
  • You have a bunch of typos: `cout` should be `count`. You need to declare `records` and `count`. You're missing a `;` after `scanf(" %d", &carro.ar)`. After I fixed these problems, the code compiled without any errors. I don't get the error you mention. – Barmar Jun 27 '22 at 18:50
  • I did fix the typos and the ; was probably my mistake when posting the question. The compiling issue also vanished after I properly rewrote it, still doesn't update the file... – Raphael Ozono Jun 27 '22 at 18:59
  • You have no `fclose(fp);` in the function. – Barmar Jun 27 '22 at 19:04
  • I did add fclose(fp), I also tried adding fflush later since it didn't work – Raphael Ozono Jun 27 '22 at 19:10
  • Are you sure it's finding the item to replace? Add a `printf()` into the `if (carro.id == id)` block. – Barmar Jun 27 '22 at 19:13
  • I added a printf() inside the if statement, it did print so it must've found it, right? – Raphael Ozono Jun 27 '22 at 19:17
  • Then I don't know why it's not updating the file. – Barmar Jun 27 '22 at 19:19
  • I'll do some debugging, I know I thanked you multiple times, but I really do appreciate you taking the time, and sorry about not being able to make it work even with you assistance. Have a great day. – Raphael Ozono Jun 27 '22 at 19:20
  • Back again, I changed the logic and it worked. Though it only did because of the fseek function you suggested. – Raphael Ozono Jun 28 '22 at 21:33