Thread: setting a position in a binary file

  1. #16
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Why, if payrollTotals[1000] is of type float, are you looping on "fread(&payrollTotals[i], sizeof(int), 1, f)"?????

    If you use SEEK_CURR rather than SEEK_SET, no need to keep track of the position using bP. Only need to account for the fact that fread() increases the file pointer (by the amount of data it reads).

    Also, don't use magic values (36, 60, etc) if you can avoid it. 36 is presumably offsetof(your_struct, some_member_of_struct) and 60 is presumably sizeof(your_struct). Those simple changes will help your code work with different compilers.


    Bear in mind that the size of structs (and struct members) is compiler dependent. So, if you build your code with a different compiler, odds are it will not be able to read your file correctly - the amount of data read and written by will vary with compiler.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  2. #17
    Registered User
    Join Date
    Jan 2013
    Posts
    42
    Grumpy, well at least you acknowledge it

  3. #18
    Registered User
    Join Date
    Jan 2013
    Posts
    42
    I guess I never changed the fread loop because float and int are the same byte size but if only for consistency I should, and if other compilers allocate more bytes to a float rather than an int, I would have probelms. What could I use instead of 36 to seek to that position. Is there a data type I can create to represent that many bytes or is there a way of telling it that I want the 6th value.
    Last edited by generaltso78; 02-23-2013 at 07:51 PM.

  4. #19
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by generaltso78 View Post
    I guess I never changed the fread loop because float and int are the same byte size but if only for consistency I should, and if other compilers allocate more bytes to a float rather than an int, I would have probelms.
    Your choice of words implies you think it is an irrelevant detail that can be ignored. That is an effective way of developing bad habits that WILL eventually bite you in real-world programming. Attention to detail is a primary weapon in the ongoing battle to generate fault-free code.

    There are real-world compilers for which sizeof(int) != sizeof(float). Even better, there are real-world compilers for which sizeof(int) is configurable.

    Quote Originally Posted by generaltso78 View Post
    What could I use instead of 36 to seek to that position. Is there a data type I can create to represent that many bytes or is there a way of telling it that I want the 6th value.
    I've already mentioned the offsetof() macro. It is specified in the standard header <stddef.h>.

    The standard type used to represent sizes of types is called size_t. It is an unsigned integral type that, again, is specified in <stddef.h>.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #20
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    @generaltso78
    You need to post your actual struct, and the code you use to fwrite it to a file.
    Without it, it's impossible to tell whether any of your fseek / fread code makes any sense at all.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #21
    Registered User
    Join Date
    Jan 2013
    Posts
    42
    Grumpy,

    To play devils advocate, if everyone who programmed wrote fault-free code then would there not be a lot less programmers. That being said, I do want to be in the group of "good" programmers at some point. It is difficult because, my class doesn't even attempt to convey portability or stress good habits even when the bad ones produce the same result in that particular assignment. Granted this is the class which comes directly after the intro class. The assignment I have written, will "sadly" get me a 100 but only because it does everything the instructor wanted it to do. I could just stop there but I want it to be sound. I am still at the infant stage of writing/designing but I understand the importance of good fundamentals.

    Here is the two structs that my program uses. I do have a EMPLOYEE person[10000];

    Code:
    typedef struct {
        int month;
        int day;
        int year;
    }DATE;
    
    
    typedef struct {
        char name[20];
        int age;
        float hourlyWage;
        float hoursWkd;
        float otHoursWkd;
        float regPay;//computed
        float otPay;//computed
        float totalPay;//computed
        DATE  payDate;                      //this is a struct inside a struct
    }EMPLOYEE;
    and here is the function where the person arrays are populated and written to file

    Code:
        char sValidate[5] = "exit";
        FILE *f;
        int count = 0, i = 0;
        f = fopen("employeeRecords.bin", "ab");
        
        while (strcmp( sValidate, person[i].name)) {
            printf("Please enter name or type exit to return to main menu: ");
            scanf("%s", person[i].name);         //must use the '->' when passing by by refrence, must use '&' sign 
            flush;
    
    
            if (!strcmp( sValidate, person[i].name)) 
                break;
            
            printf("\nPlease enter age of %s: ", person[i].name);
            scanf("%i", &person[i].age);
            flush;
            printf("\nPlease enter the hourlyWage for %s: ", person[i].name);
            scanf("%f", &person[i].hourlyWage);
            flush;
            printf("\nPlease enter the hours worked for %s: ", person[i].name);
            scanf("%f", &person[i].hoursWkd);
        
            if (person[i].hoursWkd > 40) {
                person[i].regPay = person[i].hourlyWage * 40.0;
                person[i].otHoursWkd = person[i].hoursWkd - 40.0;
                person[i].otPay = person[i].otHoursWkd * (person[i].hourlyWage * 1.5);
                person[i].totalPay = person[i].regPay + person[i].otPay;
            }
            else {
                person[i].totalPay = person[i].hoursWkd * person[i].hourlyWage;
                person[i].regPay = person[i].totalPay;
                person[i].otHoursWkd = 0.0; person[i].otPay = 0.0;
            }
            flush;
            printf("\nEnter 2 digit month: ");
            scanf("%i", &person[i].payDate.month);   //must use the '->' when passing by by refrence, must use '&' sign 
            flush;
            printf("\nEnter 2 digit day: ");
            scanf("%i", &person[i].payDate.day);  //must use the '->' when passing by by refrence, must use '&' sign 
            flush;
            printf("\nEnter 4 digit year: ");
            scanf("%i", &person[i].payDate.year);   //must use the '->' when passing by by refrence, must use '&' sign 
            flush;
            fwrite(&person[i], sizeof(person[i]), 1, f);
            i++;
        }
        fclose(f);
                
    }//end function loadPayRoll
    I know this is probably not sound code, especially my exit implementation, but most of the sloppiness of my past assignments are not present in this one and the plan is to look back from future programs and know that a lot of issues above are not present in future programs.

    Thanks,

    Mike

  7. #22
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Good - so you do have structs which don't contain pointers.

    The first thing to look into is offsetof() which grumpy mentioned earlier. This will allow you to get to the field of interest in the first record.

    After that, you use sizeof() (minus a bit - you can work out how much) to step from that field to the same field in the next record.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #23
    Registered User
    Join Date
    Jan 2013
    Posts
    42
    I implemented the offsetof and it seems to work beautifully, but am I not getting the same results. The first result (using offset) returns exactly what I want but when increment the position and use SEEK_CUR inside my loop the position is obviously not going where I want it to.

    Code:
    fseek(f, offsetof(EMPLOYEE, regPay), SEEK_SET);
            while (fread(&bufferTotals[i], sizeof(float), 1, f) == 1){
            
                payrollTotal += bufferTotals[i];
                fseek(f, sizeof(56), SEEK_CUR);
                i++;
            }
    From my understanding, I should be getting the same results as before. As a follow up, for the best portability, is there an alternative to (56), like a way to represent sizeof(struct) - sizeof(struct value).

    Thanks again,

    Mike
    Last edited by generaltso78; 02-24-2013 at 04:52 PM.

  9. #24
    Registered User
    Join Date
    Jan 2013
    Posts
    42
    Wow, I just got back. looked at my problem again and wow, cant believe I had sizeof in my fseek, sorry for wasting your time if you read my last post

  10. #25
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > is there an alternative to (56), like a way to represent sizeof(struct) - sizeof(struct value).
    Well yes, sizeof(struct) - sizeof(struct value) should work, given the right things to do sizeof on.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. setting a file position pointer
    By JayCee++ in forum C++ Programming
    Replies: 3
    Last Post: 11-20-2011, 06:40 AM
  2. setting cursor position
    By scrasnu in forum C Programming
    Replies: 1
    Last Post: 10-04-2008, 10:28 AM
  3. Getting and setting cursor position
    By Spartan552 in forum Linux Programming
    Replies: 8
    Last Post: 01-14-2008, 05:27 AM
  4. How to keep track of the position in a binary file.
    By earth_angel in forum C Programming
    Replies: 4
    Last Post: 07-25-2005, 06:29 AM
  5. setting Cursor Position in C???
    By librab103 in forum C Programming
    Replies: 2
    Last Post: 07-26-2003, 02:54 PM

Tags for this Thread