Thread: Read data from binary file with condition

  1. #1
    Registered User
    Join Date
    May 2015
    Posts
    10

    Read data from binary file with condition

    Could you help me please, I'm trying to read data from binary file to linked list, but I can't understand how to add condition and read only special entries. For, example how to read cars with place = street? This the code:
    Structure:
    Code:
    typedef struct S_RacingCar {
    
        char name[12];
        int speed;
        struct S_RacingCar *next;
        struct S_RacingCar *previous;
        
    } RacingCar;
    Reading from file:
    Code:
    RacingCar *ReadNextFromFile(RacingCar *start, FILE *pFile) {
        size_t returnValue;
        if(start == NULL) {
            start = malloc(sizeof(RacingCar));
            returnValue = fread(start, sizeof(RacingCar), 1, pFile);
            start->next = NULL;
            start->previous = NULL;
        } else {
            RacingCar *indexCar = start;
            RacingCar *newCar = malloc(sizeof(RacingCar));
            while(indexCar->next != NULL) {
                indexCar = indexCar->next;
            }
            returnValue = fread(newCar, sizeof(RacingCar), 1, pFile);
            indexCar->next = newCar;
            newCar->next = NULL;
            newCar->previous = indexCar;
        }
        return start;
    }
     
    RacingCar *ReadListIn(RacingCar *start) {
         
        FILE *pFile;
        pFile = fopen("myList.bin", "rb");
        if(pFile != NULL) {
         
            CleanUp(start);
            start = NULL;
             
            fseek(pFile, 0, SEEK_END);
            long fileSize = ftell(pFile);
            rewind(pFile);
             
            int numEntries = (int)(fileSize / (sizeof(RacingCar)));
            printf("numEntries:%d\n",numEntries);
             
            int loop = 0;
            for(loop = 0; loop < numEntries; ++loop) {
                fseek(pFile, (sizeof(RacingCar) * loop), SEEK_SET);
                start = ReadNextFromFile(start, pFile);
            }
        }  else {
            printf("FILE OPEN ERROR FOR READ\n");
        }
         
        return start;
     
    }
    I tried to add the condition in while loop (ReadNextFromFile), but what should I do with returnValue. Could you help me please...
    Last edited by tawawogita; 06-01-2015 at 05:29 AM.

  2. #2
    Registered User
    Join Date
    May 2015
    Posts
    10
    True structure is:
    Code:
    typedef struct S_RacingCar {
    
        char name[12];
        char place[12];
        int speed;
        struct S_RacingCar *next;
        struct S_RacingCar *previous;
        
    } RacingCar;

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    For, example how to read cars with place = street?
    You'll probably need to read the file one record at a time until you find the record you want.

    And since you're using binary files you may want to consider using a structure that doesn't contain the "extra" pointers, possibly using two structures instead of one:
    Code:
    typedef struct Data
    {
       char name[20];
       char place[20];
       int speed;
    } Data;
    
    typedef struct RacingCar
    {
        Data car;
        struct RacingCar *next;
        struct RacingCar *pevious;
    } RacingCar;
    Then you can read and write just the "Data" to the file and not writing the pointers to the file as well.

    Jim

  4. #4
    Registered User
    Join Date
    May 2015
    Posts
    10
    jimblumberg, thank you a lot! It is a brilliant idea!!!
    But I not clearly understand how to organized a compare place == "street" in this case.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    First you do realize that you can't use the comparison operator with a string, correct?

    Next are you reading the file and building your list, then searching your list? If so then all you will need to do is traverse the list until you find the desired record.

    Edit: Why did you create a new topic for an existing problem?

    Jim
    Last edited by jimblumberg; 06-01-2015 at 09:04 AM.

  6. #6
    Registered User
    Join Date
    May 2015
    Posts
    10
    LOL I create new thread, since I think that somebody write something like "Why you don't create new thread for this problem"
    First you do realize that you can't use the comparison operator with a string, correct?

    Next are you reading the file and building your list, then searching your list? If so then all you will need to do is traverse the list until you find the desired record.
    Thank you! As a result I want to read only entries with place == street and write them to new file. I know how to write them into a new file, but I have no clue how to read only specified entries.


    P.S.
    You are a really cool ) Thank you very much!

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    but I have no clue how to read only specified entries.
    When dealing with files you read each "record" one record at a time from the beginning of the file. If it is the record you want you do what ever. But since you seem to have a structure designed for use as some kind of linked list, why don't you read the entire file and populate your list? Then do the searching in memory instead of trying to read the file over and over again.

    Jim

  8. #8
    Registered User
    Join Date
    May 2015
    Posts
    10
    jimblumberg I want to understand how to work with binary files.
    I always skip it in books and lectures, I hate files a special binary files (dat, bit etc), but at the end of my studying I want to understand how to use them and I trying to modify my program to work with it. In *nix-like systems and parallel computing it is necessary to know.

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I want to understand how to work with binary files.
    Well then what's stopping you? If you want to find specific information within the files you need to search the file. Where is your search routine? Where is a complete program that you wrote that illustrates what you don't understand. Do you even understand how to work with text files? From your previous topic that I linked earlier it doesn't seem that you do. I suggest that before you try to understand the "magic" of binary files that you thoroughly familiarize yourself with basic to intermediate text file input and output. At least with text files you can see what you're reading and writing unlike binary files where everything is hidden in bytes.

    I always skip it in books and lectures,
    Then there's your problem. Quit scrimpin on the work you be required for learnin.

    Jim

  10. #10
    Registered User
    Join Date
    May 2015
    Posts
    10
    Well then what's stopping you?
    My code isn't work... that is all.
    Then there's your problem.
    This applies to any topic in any forum.
    My code is here:
    pastebin.com/shYF7XXG (not working)
    and here:
    Code:
    RacingCar *ReadNextFromFile_mod(RacingCar *start, FILE *pFile) {
        size_t returnValue;
        if(start == NULL) {
            start = malloc(sizeof(RacingCar));
            returnValue = fread(start, sizeof(RacingCar), 1, pFile);
            start->next = NULL;
            start->previous = NULL;
        } else {
            RacingCar *indexCar = start;
            RacingCar *newCar = malloc(sizeof(RacingCar));
            while(indexCar->next != NULL) {
                indexCar = indexCar->next;
            }
            RacingCar temp;
            returnValue = fread(&temp, sizeof temp, 1, pFile);
            if (returnValue != 1) {
                if (ferror(pFile)) {
                    puts("Error reading from file");
                }
                return start;
            }
    
            if (strncmp(temp.place, "street", sizeof temp.place)) {
                return start;
            }
            indexCar->next = newCar;
            newCar->next = NULL;
            newCar->previous = indexCar;
        }
        return start;
    }
    Working strange - reading all, but printing only entries with place == street.
    Full code: pastebin.com/VThKfRsj

  11. #11
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Without seeing how you're writing the file I can't really help you read the file since reading a binary file depends on how it was written. So you need to show a small complete program that illustrates your problem.

    Jim

  12. #12
    Registered User
    Join Date
    May 2015
    Posts
    10
    Ok
    This is the code:
    Code:
    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    
    typedef struct S_RacingCar {
    
        char name[12];
        char place[12];
        int speed;
        struct S_RacingCar *next;
        struct S_RacingCar *previous;
        
    } RacingCar;
    
    void PrintList(RacingCar *start) {
        RacingCar *currentCar = start;
        int count = 0;
        
        RacingCar *ahead = NULL;
        RacingCar *behind = NULL;
        
        while(currentCar != NULL) {
            count++;
            
            ahead = currentCar->next;
            behind = currentCar->previous;
            
            printf("Car:%d Name:%s Place:%s Speed:%d Ahead:%s Behind:%s\n",count,
                currentCar->name,
                currentCar->place,
                currentCar->speed,
                (ahead == NULL) ? "None" : ahead->name,
                (behind == NULL) ? "None" : behind->name
                );
            currentCar = currentCar->next;
            ahead = NULL;
            behind = NULL;
        }    
        printf("Total Cars:%d\n",count);
    }
    
    RacingCar *MakeNewCar() {
    
        printf("Enter Name, Place And Speed: ");
        char input[16];
        fgets( input, 15, stdin);
        
        RacingCar *newCar = malloc(sizeof(RacingCar));
        sscanf(input, "%s %s %d", newCar->name, newCar->place, &newCar->speed);
        printf("Added:%s Place:%s Speed:%d\n\n",newCar->name, newCar->place, newCar->speed);
        
        newCar->next = NULL;
        newCar->previous = NULL;
        
        return newCar;
    }
    
    RacingCar *AddToStart(RacingCar *startPtr) {
        RacingCar *newCar = MakeNewCar();
        if(startPtr != NULL) {
            startPtr->previous = newCar;
            newCar->next = startPtr;
        }
        
        return newCar;
    }
    
    RacingCar *AddToEnd(RacingCar *startPtr) {
        RacingCar *returnPtr = startPtr;
        RacingCar *newCar = NULL;
        
        if(startPtr == NULL) {
            newCar = AddToStart(startPtr);
            returnPtr = newCar;
        } else {
            RacingCar *indexCar = startPtr;
            while (indexCar->next != NULL) {
                indexCar = indexCar->next;
            }
            newCar = MakeNewCar();
            indexCar->next = newCar;
            newCar->next = NULL;
            newCar->previous = indexCar;
        }
        return returnPtr;
    }
    
    RacingCar *Delete(RacingCar *startPtr) {
    
        printf("Enter Name To Delete:");
        char input[16];
        fgets(input, 15, stdin);
        
        RacingCar *carRef = startPtr;
        RacingCar *carToDelete = NULL;
        
        while(carRef != NULL) {
        
            if(strncmp(input, carRef->name, strlen(carRef->name)) == 0) {
                carToDelete = carRef;
                break;
            }
            
            carRef = carRef->next;
        }
        
        if(startPtr != NULL && carToDelete == startPtr) {
            if(carToDelete->next != NULL) {
                carToDelete->next->previous = NULL;
                startPtr = carToDelete->next;
            } else {
                startPtr = NULL;
            }
        } else {
            if(carToDelete != NULL) {
                if(carToDelete->previous != NULL) {
                    carToDelete->previous->next = carToDelete->next;
                }
                
                if(carToDelete->next != NULL) {
                    carToDelete->next->previous = carToDelete->previous;
                }
            }
        }
        
        if(carToDelete != NULL) {
            carToDelete = NULL;
            free(carToDelete);
        }
        
        return startPtr;
        
    }
    
    RacingCar *Insert(RacingCar *startPtr) {
        printf("Insert New Car After Car:");
        char input[16];
        fgets(input, 15, stdin);
        
        RacingCar *afterCar = startPtr;
        RacingCar *newCar = NULL;
        
        if(strncmp(input, afterCar->name, strlen(afterCar->name)) == 0) {
            newCar = MakeNewCar();
        } else {
            while(afterCar->next != NULL) {
                afterCar = afterCar->next;
                if(strncmp(input, afterCar->name, strlen(afterCar->name)) == 0) {
                    newCar = MakeNewCar();
                    break;
                }
            }
        }
        
        if(newCar != NULL) {
            newCar->next = afterCar->next;
            if(newCar->next != NULL) {
                newCar->next->previous = newCar;
            }
            afterCar->next = newCar;
            newCar->previous = afterCar;
        } else {
            printf("Car Not Found\n");
        }
        
        return startPtr;
    }
    
    void CleanUp(RacingCar *start) {
        
        RacingCar *freeMe = start;
        RacingCar *holdMe = NULL;    
        while(freeMe != NULL) {
            holdMe = freeMe->next;
            printf("Free Name:%s Place:%s Speed:%d\n",
                freeMe->name,
                freeMe->place,
                freeMe->speed);
            free(freeMe);
            freeMe = holdMe;
        }    
    }
    
    void WriteListToFile(RacingCar *start) {
        FILE *pFile;
        pFile = fopen("myList.bin", "wb");
        
        if(pFile != NULL) {
            RacingCar *currentCar = start;
            
            RacingCar *holdNext = NULL;
            RacingCar *holdPrevious = NULL;
            
            while(currentCar != NULL) {
                holdNext = currentCar->next;
                holdPrevious = currentCar->previous;
                
                currentCar->next = NULL;
                currentCar->previous = NULL;
                
                fseek(pFile, 0, SEEK_END);
                fwrite(currentCar, sizeof(RacingCar), 1, pFile);
                
                printf("Writing:%s to file\n",currentCar->name);
                
                currentCar->next = holdNext;
                currentCar->previous = holdPrevious;
                
                holdNext = NULL;
                holdPrevious = NULL;
                
                currentCar = currentCar->next;
            }
            fclose(pFile);
            pFile = NULL;
        } else {
            printf("FILE OPEN ERROR\n");
        }
        
    }
    
    RacingCar *ReadNextFromFile(RacingCar *start, FILE *pFile) {
        size_t returnValue;
        if(start == NULL) {
            start = malloc(sizeof(RacingCar));
            returnValue = fread(start, sizeof(RacingCar), 1, pFile);
            start->next = NULL;
            start->previous = NULL;
        } else {
            RacingCar *indexCar = start;
            RacingCar *newCar = malloc(sizeof(RacingCar));
            while(indexCar->next != NULL) {
                indexCar = indexCar->next;
            }
            returnValue = fread(newCar, sizeof(RacingCar), 1, pFile);
            indexCar->next = newCar;
            newCar->next = NULL;
            newCar->previous = indexCar;
        }
        return start;
    }
    
    RacingCar *ReadNextFromFile_mod(RacingCar *start, FILE *pFile) {
        size_t returnValue;
        if(start == NULL) {
            start = malloc(sizeof(RacingCar));
            returnValue = fread(start, sizeof(RacingCar), 1, pFile);
            start->next = NULL;
            start->previous = NULL;
        } else {
            RacingCar *indexCar = start;
            RacingCar *newCar = malloc(sizeof(RacingCar));
            while(indexCar->next != NULL) {
                indexCar = indexCar->next;
            }
            RacingCar temp;
            returnValue = fread(&temp, sizeof temp, 1, pFile);
            if (returnValue != 1) {
                if (ferror(pFile)) {
                    puts("Error reading from file");
                }
                return start;
            }
    
            if (strncmp(temp.place, "street", sizeof temp.place)) {
                return start;
            }
            indexCar->next = newCar;
            newCar->next = NULL;
            newCar->previous = indexCar;
        }
        return start;
    }
    
    RacingCar *ReadListIn(RacingCar *start) {
        
        FILE *pFile;
        pFile = fopen("myList.bin", "rb");
        if(pFile != NULL) {
        
            CleanUp(start);
            start = NULL;
            
            fseek(pFile, 0, SEEK_END);
            long fileSize = ftell(pFile);
            rewind(pFile);
            
            int numEntries = (int)(fileSize / (sizeof(RacingCar)));
            printf("numEntries:%d\n",numEntries);
            
            int loop = 0;
            for(loop = 0; loop < numEntries; ++loop) {
                fseek(pFile, (sizeof(RacingCar) * loop), SEEK_SET);
                start = ReadNextFromFile(start, pFile);
            }
        }  else {
            printf("FILE OPEN ERROR FOR READ\n");
        }
        
        return start;
    
    }
    
    RacingCar *ReadListIn_mod(RacingCar *start) {
        
        FILE *pFile;
        pFile = fopen("myList.bin", "rb");
        if(pFile != NULL) {
        
            CleanUp(start);
            start = NULL;
            
            fseek(pFile, 0, SEEK_END);
            long fileSize = ftell(pFile);
            rewind(pFile);
            
            int numEntries = (int)(fileSize / (sizeof(RacingCar)));
            printf("numEntries:%d\n",numEntries);
            
            int loop = 0;
            for(loop = 0; loop < numEntries; ++loop) {
                fseek(pFile, (sizeof(RacingCar) * loop), SEEK_SET);
                start = ReadNextFromFile_mod(start, pFile);
            }
        }  else {
            printf("FILE OPEN ERROR FOR READ\n");
        }
        
        return start;
    
    }
    
    int main() {    
        
        char command[16];
        char input[16];    
        
        RacingCar *start = NULL;
        
        while( fgets( input, 15, stdin) ) {
            
            sscanf(input,"%s",command);    
            
            if ( strncmp(command, "quit", 4) == 0) {
                printf("\n\nBreaking...\n");
                break;        
            } else if ( strncmp(command, "print", 5) == 0) {
                PrintList(start);
            } else if ( strncmp(command, "write", 5) == 0) {
                WriteListToFile(start);
            } else if ( strncmp(command, "read", 4) == 0) {
                start = ReadListIn_mod(start);
            } else if ( strncmp(command, "addstart", 8) == 0) {
                start = AddToStart(start);
                PrintList(start);
            } else if ( strncmp(command, "add", 3) == 0) {
                start = AddToEnd(start);
                PrintList(start);
            } else if ( strncmp(command, "insert", 6) == 0) {
                if(start == NULL) {
                    start = AddToStart(start);
                } else {
                    start = Insert(start);
                }
                PrintList(start);
            }
        }
        
        CleanUp(start);
        
        return 0;
    
    }
    Run it and input
    add \Enter
    ff male 1\Enter
    add \Enter
    ss another 2\Enter
    add \Enter
    tt male 3\Enter
    write\Enter
    Writing:ff to file
    Writing:ss to file


    Writing:tt to file
    read\Enter
    numEntries:3
    print\Enter
    Total Cars:1

    How to fix it???

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 12-07-2013, 04:33 PM
  2. Replies: 6
    Last Post: 12-06-2013, 11:39 PM
  3. Replies: 12
    Last Post: 06-18-2012, 08:23 AM
  4. Replies: 21
    Last Post: 11-03-2007, 02:56 PM
  5. pull out data frm a text file based on a condition
    By nirmala.s in forum C Programming
    Replies: 21
    Last Post: 11-27-2006, 12:56 AM