简体   繁体   中英

How to read a specific line from binary file into a structure C

Essentially, I printed to a binary file using fseek() and fwrite(). However, I want to read the contents from a specific line into a structure. I also used fseek() and fread() to obtain the contents. I prompted the user to enter a code. From what I have learnt, I would use the value obtained from the user to use in the fseek function to get the specific line to start read from. Apparently, the fseek to read the contents does not work, I am getting gibberish essentially when it is displayed on the screen. Assistance is greatly appreciated.

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


typedef struct registered
{
    int compcode;
    char compname[20];
    int pinID;
    int custID;
    char IDtype[15];
    int compID;
}REGISTERED;

void AddUpdate(REGISTERED info);
void SellPetrol();

void main(){
    REGISTERED info = {0, "Apple", 0, 0, "passport", 0};
    REGISTERED list;
    AddUpdate(info);
    SellPetrol();

}

void AddUpdate(REGISTERED info){
    int choice;


    FILE *registryfile = NULL;
    registryfile = fopen("Sales.dat", "ab");


    if (registryfile == NULL){
        perror("Error: ");
    }
    else{
        do{


            printf("Company Code: ");
            scanf("%d", &info.compcode);
            printf("Company Name: ");
            scanf("%s", &info.compname);
            printf("Pin: ");
            scanf("%d", &info.pinID);
            printf("Customer ID: ");
            scanf("%d", &info.custID);
            printf("ID type: ");
            scanf("%s", &info.IDtype);
            printf("Company ID: ");
            scanf("%d", &info.compID);  

            fseek(registryfile, (info.compcode - 1) * sizeof(REGISTERED), SEEK_SET);
            fwrite(&info, sizeof(REGISTERED), 1, registryfile); 


            printf("Enter choice: ");
            scanf("%d", &choice);
        }while(choice == 1);
    }
        printf("\tCompany Code: %d\t\n", info.compcode);
        printf("\tCustomer ID: %d\t\n", info.custID);
    fclose(registryfile);
}

void SellPetrol(){

    int code = 0, PIN;

    REGISTERED list;
    FILE *registryfile = NULL;
    registryfile = fopen("Sales.dat", "rb");

    if (registryfile == NULL){
        perror("Error: ");
    }
    else{

        printf("Please enter the company code: ");
        scanf("%d", &code);
    //  printf("Please enter the PIN: ");
    //  scanf("%d", &PIN);

        rewind(registryfile);
            fseek(registryfile, (code - 1) * sizeof(REGISTERED), SEEK_SET);
            fread(&list, sizeof(REGISTERED), 1, registryfile); //reads data into list

            fflush(stdin);  
            printf("Company Code: %d\n", list.compcode);
            printf("Company Name: %s\n", list.compname);
            printf("Pin: %d\n", list.pinID);
            printf("Customer ID: %d\n", list.custID);
            printf("ID Type: %s\n", list.IDtype);
            printf("Company ID: %d\n", list.compID);

    }
    fclose(registryfile);
}

It seems whichever method you're using to learn C is causing troubles, as the mistakes you seem to be making are common. I suggest reading a book, such as K&R2E... Do the exercises as you stumble across them; don't move on until you've completed them, and ask questions about them if necessary.


Don't fflush(stdin) . fflush doesn't do what you think it does.


Check return values for functions such as fopen , scanf , fseek , fread , even fwrite . You'll probably find that your fread or scanf is returning a value indicating failure , hence the gibberish you speak of.


Be aware that C uses pass-by-value semantics ONLY . The source of at least one error in your code is a misunderstanding regarding these semantics. Namely, AddUpdate has no way to modify the variable declared within main , as it recieves a copy of that variable; at this point it seems void AddUpdate(REGISTERED info) should be void AddUpdate(void) and info should be declared within AddUpdate .


scanf("%s", &info.compname); probably doesn't do what you think it does. The %s directive tells scanf to read (metalinguistically speaking) a word (that is, a whitespace-delimitered token), not a line (a newline delimitered token), of user input. You probably want int x = scanf("%19[^\\n]", info.compname); or better yet, char *x = fgets(info.compname, sizeof info.compname, stdin); ...


void main() is unportable , and so is #include <conio.h> . You probably want int main(void) and ... you don't appear to be using any functions from <conio.h> , so you probably don't want anything in place of that. In C99, a main function that has no return statement will implicitly return 0; without a warning issued.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM