problems opening a binary file to screen for viewing.

Hi,

I have a code that requires a birnary file to be opened for output to the screen but when I execute the code it says "File can not be opened"
here is my code
int readBinaryRecord(BirdRecord all[],string option,BirdLocationAllWrite BirdOrLocationOrAll)
{
      ifstream inFile;

      inFile.open(inFileName,ios::binary);

      if(inFile.fail() )
      {
            cerr<<"FILE "<<inFileName<<" Could not be Opened ";

            getch();

            exit(1);
      }

      int idx=0;

      BirdRecord birds;

      while(! ( inFile.eof() ) )
      {
            inFile.read(reinterpret_cast<char*>(&birds),sizeof(birds) );  //Read a binary record.

            if(BirdOrLocationOrAll== BIRD )//for option 3, that is view sightings on the basis of a particular type of birds.
            {
                  if(birds.type==option)
                  {
                        all[idx].firstDate=birds.firstDate;
                        all[idx].firstMonth=birds.firstMonth;
                        all[idx].firstYear=birds.firstYear;

                        all[idx].latestDate=birds.latestDate;
                        all[idx].latestMonth=birds.latestMonth;
                        all[idx].latestYear=birds.latestYear;

                        strcpy(all[idx].type,birds.type);
                        strcpy(all[idx].location,birds.location);

                        all[idx].numberOfBirds=birds.numberOfBirds;


                        idx++;
                  }
            }

            if(BirdOrLocationOrAll==LOCATION)//for option 4, that is view sightings on the basis of a particular type of location.
            {
                  if(birds.location==option)
                  {
                        all[idx].firstDate=birds.firstDate;
                        all[idx].firstMonth=birds.firstMonth;
                        all[idx].firstYear=birds.firstYear;

                        all[idx].latestDate=birds.latestDate;
                        all[idx].latestMonth=birds.latestMonth;
                        all[idx].latestYear=birds.latestYear;

                        strcpy(all[idx].type,birds.type);
                        strcpy(all[idx].location,birds.location);

                        all[idx].numberOfBirds=birds.numberOfBirds;


                        idx++;
                  }
            }
            if(BirdOrLocationOrAll==ALL)//for option 5, view all birds in all location.
            {
                  all[idx].firstDate=birds.firstDate;
                  all[idx].firstMonth=birds.firstMonth;
                  all[idx].firstYear=birds.firstYear;

                  all[idx].latestDate=birds.latestDate;
                  all[idx].latestMonth=birds.latestMonth;
                  all[idx].latestYear=birds.latestYear;

                  strcpy(all[idx].type,birds.type);
                  strcpy(all[idx].location,birds.location);

                  all[idx].numberOfBirds=birds.numberOfBirds;
                  idx++;
            }
      }
      return idx;
      }
there is a header file with
const char inFileName[] = "birds.bin";//name of file
thanks

Kaz
KazITAsked:
Who is Participating?
 
rstaveleyConnect With a Mentor Commented:
Pasting a binary file into a web form doesn't really work. If you can look at the directory listing, you'll be able to provide the answer to 1. However, looking at the struct we can see that BIRD_SIZE and LOCATION_SIZE are both numbers which are divisible by sizeof(int)=4 (assuming your system is a 32-bit one) and all other data are ints, which means that packing is unlikely to be your problem.

Aha... I think I just spotted your problem:

> if(birds.type==option)

This comparison, will only work if birds.type has a '\0' terminus, because birds.type is a char array. Your binary file posting doesn't really make it clear if "whistling ducksÌÌÌÌ" has a '\0' after the 's'.

You could try replacing this comparison with:

   if (option == string(birds.type,option.size())

This creates a temporary string using option.size() characters from birds.type and compares option with the temporary string.
0
 
KazITAuthor Commented:
also I don't want the binary file records already existing to be deleted as I have to update various records in it with  a different function.
0
 
lemmeCCommented:
This might be a trivial question. Is the header file included in the codefile?
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
lemmeCCommented:
Also, do you have permissions to open the file?
0
 
KazITAuthor Commented:
lemmeC...yes that header file is included.
How do I know if i have permissions to open the file? I can click on it in the project and it opens ok...but other than that I'm not sure what you mean sorry.
0
 
lemmeCCommented:
Try replacing:
inFile.open(inFileName,ios::binary);

with
inFile.open(inFileName,ios::binary|ios::in);

0
 
lemmeCCommented:
>> I can click on it in the project and it opens ok <<
Then the permissions are fine.
0
 
KazITAuthor Commented:
thanks lemmeC.

The file seems to open but I must have a problem in my function because it says the number of birds or locations are zero....and I know there are those particular records there in the binary file
0
 
rstaveleyCommented:
(1) What is the length of your file?
(2) How many BirdRecords do you expect there to be in that file?
(3) Show us your BirdRecord class/struct definition.
(4) At the beginning of your program printf or cout sizeof(BirdRecord) and see if it differs from your expectation.

My guess is that struct/class BirdRecord is not packed and that you are therefore reading the wrong number of bytes each time and that the bytes read are being read into the wrong offsets in your struct.

On a lot of compilers you can byte-pack the struct by using the #pragma pack(1) directive as follows:
--------8<--------
#pragma pack(1)
struct BirdRecord
{
  // ...
};
#pragma pack()
--------8<--------

Beware that this is not portable, but it works with GCC and VC.
0
 
KazITAuthor Commented:
This is a copy of the binary file.  As you can see there are many records in this file.

ÍÔpelicansÌÌÌÌÌÌÌÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌÎ Òwood ducksÌÌÌÌÌÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌ6ÔÔblack ducksÌÌÌÌÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌ<ÎÓwhistling ducksÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌb Ì Ñmagpie geeseksÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌd
ÎÒking fishersksÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌÌ
Ówater fowlsksÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌ`ÏÐdab chickssksÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌ Ï
Òspoon billsksÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌ#      Ï      ÒcormorantsksÌÌÌÌAwonga DamÌÌÌÌÌÌÌÌÌM
      ÏÓpelicanssksÌÌÌÌFairburn DamÌÌÌÌÌÌÌ2 ÌÔwood ducksksÌÌÌÌFairburn DamÌÌÌÌÌÌÌ] ÌÔblack ducksksÌÌÌÌFairburn DamÌÌÌÌÌÌÌø
ÌÑwhistling ducksÌÌÌÌFairburn DamÌÌÌÌÌÌÌÏ      Òmagpie geeseksÌÌÌÌFairburn DamÌÌÌÌÌÌÌ/king fishersksÌÌÌÌFairburn DamÌÌÌÌÌÌÌÎÑwater fowlsksÌÌÌÌFairburn DamÌÌÌÌÌÌÌB ÌÓdab chickssksÌÌÌÌFairburn DamÌÌÌÌÌÌÌZÏ            Ðspoon billsksÌÌÌÌFairburn DamÌÌÌÌÌÌÌ? ÏÐcormorantsksÌÌÌÌFairburn DamÌÌÌÌÌÌÌ>Í
ÐpelicanssksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌÎÔwood ducksksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌ[ÎÑblack ducksksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌÎÓwhistling ducksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌ0ÌÓmagpie geeseksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌÎÔking fishersksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌDÏ Ñwater fowlsksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌÌÔdab chickssksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌÙÍÔspoon billsksÌÌÌÌTinaroo DamÌÌÌÌÌÌ̉ÎÐcormorantsksÌÌÌÌTinaroo DamÌÌÌÌÌÌÌÍÓpelicanssksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌÎÑwood ducksksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ  Ï Óblack ducksksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ
!      Ì Ówhistling ducksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ9"Ï Ómagpie geeseksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ_#
Ï      Óking fishersksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ`$ ÌÒwater fowlsksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ% ÎÓdab chickssksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌL&ÏÓspoon billsksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ['
ÌÔcormorantsksÌÌÌÌIvanhoe DamÌÌÌÌÌÌÌ=(Í ÑpelicanssksÌÌÌÌLake VictoriaÌÌÌÌÌÌ )Ï      Òwood ducksksÌÌÌÌLake VictoriaÌÌÌÌÌÌ*Î      Òblack ducksksÌÌÌÌLake VictoriaÌÌÌÌÌÌ>+ÍÑwhistling ducksÌÌÌÌLake VictoriaÌÌÌÌÌÌ ,
Î Ñmagpie geeseksÌÌÌÌLake VictoriaÌÌÌÌÌÌ-Ï Òking fishersksÌÌÌÌLake VictoriaÌÌÌÌÌÌ.
Ï Ðwater fowlsksÌÌÌÌLake VictoriaÌÌÌÌÌÌ</ÏÒdab chickssksÌÌÌÌLake VictoriaÌÌÌÌÌÌ0 Í      Òspoon billsksÌÌÌÌLake VictoriaÌÌÌÌÌÌ+1
Î      
ÐcormorantsksÌÌÌÌLake VictoriaÌÌÌÌÌÌ      2ÌÑpelicanssksÌÌÌÌBurnett RiverÌÌÌÌÌÌ3      ÌÓwood ducksksÌÌÌÌBurnett RiverÌÌÌÌÌÌA4Ï Ðblack ducksksÌÌÌÌBurnett RiverÌÌÌÌÌÌ_5ÌÐwhistling ducksÌÌÌÌBurnett RiverÌÌÌÌÌÌY6 ÍÑmagpie geeseksÌÌÌÌBurnett RiverÌÌÌÌÌÌ7Ï      Ðking fishersksÌÌÌÌBurnett RiverÌÌÌÌÌÌ8       ÍÔwater fowlsksÌÌÌÌBurnett RiverÌÌÌÌÌÌD9ÍÔdab chickssksÌÌÌÌBurnett RiverÌÌÌÌÌÌ:ÏÔspoon billsksÌÌÌÌBurnett RiverÌÌÌÌÌ̲; Ì
ÓcormorantsksÌÌÌÌBurnett RiverÌÌÌÌÌÌP<       Í ÒpelicanssksÌÌÌÌBurdekin RiverÌÌÌÌÌ.=Ï
Òwood ducksksÌÌÌÌBurdekin RiverÌÌÌÌÌK>Ï       Óblack ducksksÌÌÌÌBurdekin RiverÌÌÌÌÌ>?ÍÒwhistling ducksÌÌÌÌBurdekin RiverÌÌÌÌÌ>@      ÌÔmagpie geeseksÌÌÌÌBurdekin RiverÌÌÌÌÌ      A
ÌÒking fishersksÌÌÌÌBurdekin RiverÌÌÌÌÌbBÍÑwater fowlsksÌÌÌÌBurdekin RiverÌÌÌÌÌ5C ÎÐdab chickssksÌÌÌÌBurdekin RiverÌÌÌÌÌD       Î
Óspoon billsksÌÌÌÌBurdekin RiverÌÌÌÌÌWE ÍÑcormorantsksÌÌÌÌBurdekin RiverÌÌÌÌÌPF

Ï
ÐpelicanssksÌÌÌÌPioneer RiverÌÌÌÌÌ9GÎÔwood ducksksÌÌÌÌPioneer RiverÌÌÌÌÌCHÌÓblack ducksksÌÌÌÌPioneer RiverÌÌÌÌÌ[I      Î
Òwhistling ducksÌÌÌÌPioneer RiverÌÌÌÌÌWJÎÔmagpie geeseksÌÌÌÌPioneer RiverÌÌÌÌÌØKÏÓking fishersksÌÌÌÌPioneer RiverÌÌÌÌÌbL      ÍÓwater fowlsksÌÌÌÌPioneer RiverÌÌÌÌÌSM ÌÒdab chickssksÌÌÌÌPioneer RiverÌÌÌÌÌ NÎÔspoon billsksÌÌÌÌPioneer RiverÌÌÌÌÌaOÏÔcormorantsksÌÌÌÌPioneer RiverÌÌÌÌ̪PÌÓpelicanssksÌÌÌÌMary RivererÌÌÌÌÌQÍÒwood ducksksÌÌÌÌMary RivererÌÌÌÌÌRR
Í Òblack ducksksÌÌÌÌMary RivererÌÌÌÌÌUSÏÐwhistling ducksÌÌÌÌMary RivererÌÌÌÌÌ(TÏÓmagpie geeseksÌÌÌÌMary RivererÌÌÌÌÌ=UÏÓking fishersksÌÌÌÌMary RivererÌÌÌÌÌVÍ Ðwater fowlsksÌÌÌÌMary RivererÌÌÌÌÌ W      ÌÑdab chickssksÌÌÌÌMary RivererÌÌÌÌÌ_X
ÌÓspoon billsksÌÌÌÌMary RivererÌÌÌÌÌ"Y Ï
ÓcormorantsksÌÌÌÌMary RivererÌÌÌÌÌZ
ÍÔpelicanssksÌÌÌÌFitzroy RiverÌÌÌÌÌû[      Í Ðwood ducksksÌÌÌÌFitzroy RiverÌÌÌÌÌ\Í
Ñblack ducksksÌÌÌÌFitzroy RiverÌÌÌÌÌG]      Î      Òwhistling ducksÌÌÌÌFitzroy RiverÌÌÌÌÌO^Î Ñmagpie geeseksÌÌÌÌFitzroy RiverÌÌÌÌÌ_      Ì
Òking fishersksÌÌÌÌFitzroy RiverÌÌÌÌÌ`       ÎÓwater fowlsksÌÌÌÌFitzroy RiverÌÌÌÌÌ;a
ÌÔdab chickssksÌÌÌÌFitzroy RiverÌÌÌÌÌ´bÎ Ðspoon billsksÌÌÌÌFitzroy RiverÌÌÌÌÌ+cÌÔcormorantsksÌÌÌÌFitzroy RiverÌÌÌÌÌY      



This is a copy of BirdRecord Struct
struct BirdRecord            //define a BirdRecord struct
      {
      int reference;//to store the key
      int firstDate;//date variable store date 1st sighting
      int firstMonth;
      int firstYear;
      int latestDate;
      int latestMonth;
      int latestYear;
      char type[BIRD_SIZE];//constant int defined in const.h
      char location[LOCATION_SIZE];//date variable store date last sighting
      //constant int defined in const.h
      int numberOfBirds;
      };

this is a copy of the constants header file
#ifndef CONST_H
#define CONST_H

#include <string>

using std::string;

enum BirdLocationAllWrite{BIRD,LOCATION,ALL,WRITE}; //If to read for option 3, or for option 4, or for option 5, or for option 2(i.e, to write).

const int MAX_SIZE = 10 ;      // Number of bird types & the number of locations
const int BIRD_SIZE = 20 ;     // For printing
const int LOCATION_SIZE = 20 ; // For printing

const int LINES_PER_PAGE = 15;  // To pause the display

const int MENU_CHOICES = 5;

const int MAX_NUMBER_OF_ENTRIES = 100;

// The species of birds

const string BIRD_TYPE[MAX_SIZE] = { "pelicans", "wood ducks", "black ducks", "whistling ducks",
                                                      "magpie geese", "king fishers", "water fowl", "dab chicks",
                                                      "spoon bills", "cormorants" } ;
// The locations
const string LOCATIONS[MAX_SIZE] = { "Awonga Dam", "Fairburn Dam", "Tinaroo Dam", "Ivanhoe Dam",
                                                      "Lake Victoria", "Burnett River", "Burdekin River",
                                                      "Pioneer River", "Mary River", "Fitzroy River" } ;

#endif
0
 
rstaveleyCommented:
>    if (option == string(birds.type,option.size())

Missing paren:

   if (option == string(birds.type,option.size()))
0
 
KazITAuthor Commented:
thanks for the comment rstaveley.  After implementation of your advices the same output comes to screen....here's the exe file output
          Bird Watching Records Program
        --------------------------------

                1. View sightings from the last excursion

                2. Update the records with the latest sightings

                3. View sightings of a particular type of bird

                4. View sightings of birds in a particular location

                5. View all sightings

                0. Exit

        ---------------------------------

Please enter your selection:  3
        1. pelicans
        2. wood ducks
        3. black ducks
        4. whistling ducks
        5. magpie geese
        6. king fishers
        7. water fowl
        8. dab chicks
        9. spoon bills
        10. cormorants

        Please enter your selection 1
   Sightings                                                       Number
   First        Latest               Bird Type          Location   of Birds
--------------------------------------------------------------------------------

 Total No Of Birds for pelicans are 0
--------------------------------------------------------------------------------

Press any key to continue
0
 
rstaveleyCommented:
In your binary file, I see pelicans listed as "pelicanssksÌÌÌÌ", which makes me suspect that your binary data is corrupt. It looks like the trailing "sksÌÌÌÌ" is left over from the "whistling ducksÌÌÌÌ" entry. However, the method I described would, I expect have worked with this, if by pressing '1' you got the BIRD_TYPE[0].

Since this is a console program can you try adding the following debug to readBinaryRecord?

--------8<--------
int readBinaryRecord(BirdRecord all[],string option,BirdLocationAllWrite BirdOrLocationOrAll)
{
    cout << "Debug: option is \"" << option << "\" and BirdOrLocationOrAll is " << BirdOrLocationOrAll << '\n';
    // ... continues as before
}
--------8<--------

If that doesn't shed any light on the problem, try displaying the comparison strings.

e.g.
--------8<--------
   string comparison(birds.type,option.size());
   if (option == comparison) {
        cout << "Debug: option is \"" << option << "\" and matched comparison is \"" << comparison << "\"\n";
       // ...as before
   }
   else {
        cout << "Debug: option is \"" << option << "\" and unmatched comparison is \"" << comparison << "\"\n";
   }
--------8<--------
0
 
KazITAuthor Commented:
This is the output with your debug option
Please enter your selection:  3
        1. pelicans
        2. wood ducks
        3. black ducks
        4. whistling ducks
        5. magpie geese
        6. king fishers
        7. water fowl
        8. dab chicks
        9. spoon bills
        10. cormorants

        Please enter your selection 1
Debug: option is"pelicans" and BirdOrLocatioOrAll is0
   Sightings                                                       Number
   First        Latest               Bird Type          Location   of Birds
--------------------------------------------------------------------------------

 Total No Of Birds for pelicans are 0
--------------------------------------------------------------------------------

Press any key to continue
0
 
KazITAuthor Commented:
sorry i didn't include the second part...let me try that again
0
 
rstaveleyCommented:
> Debug: option is"pelicans" and BirdOrLocatioOrAll is0

OK, so that sanity-checks your user-interface. Can you see what it displayed by the comparison debug?

i.e.
--------8<--------
   while(! ( inFile.eof() ) )
     {
          inFile.read(reinterpret_cast<char*>(&birds),sizeof(birds) );  //Read a binary record.

          if(BirdOrLocationOrAll== BIRD )//for option 3, that is view sightings on the basis of a particular type of birds.
          {
               if(birds.type==option)
               {
                string comparison(birds.type,option.size());
                if (option == comparison)
                {
                     cout << "Debug: option is \"" << option << "\" and matched comparison is \"" << comparison << "\"\n";
                    // ...as before
                }
                else
                {
                     cout << "Debug: option is \"" << option << "\" and unmatched comparison is \"" << comparison << "\"\n";
                }
           }

    // ...etc
--------8<--------
0
 
rstaveleyCommented:
Oops bad cut, copy and pasting... this is what I meant....
--------8<--------
   while(! ( inFile.eof() ) )
     {
          inFile.read(reinterpret_cast<char*>(&birds),sizeof(birds) );  //Read a binary record.

          if(BirdOrLocationOrAll== BIRD )//for option 3, that is view sightings on the basis of a particular type of birds.
          {
                string comparison(birds.type,option.size());
                if (option == comparison)
                {
                     cout << "Debug: option is \"" << option << "\" and matched comparison is \"" << comparison << "\"\n";
                    // ...as before
                }
                else
                {
                     cout << "Debug: option is \"" << option << "\" and unmatched comparison is \"" << comparison << "\"\n";
                }
           }

    // ...etc
--------8<--------
0
 
KazITAuthor Commented:
dont know if i am doing something wrong but I get compiler errors now one being
"illegal escape sequence" at
                     cout << "Debug: option is \"" << option << "\" and matched comparison is \"" << comparison << "\"\n";
0
 
KazITAuthor Commented:
sorry my mistake the illegal escape sequence error is now gone...but now it's picking up some of my other functions and saying "local funtion definitions are illegal" these are functions that compiled fine before????
0
 
KazITAuthor Commented:
I think i know what this last set of errors are relating to...I have multiple copies of the same project named bird and birds and for some reason it has taken some of the files from each when it has built and I am guessing that is the reason for this latest set of errors
0
 
KazITAuthor Commented:
My apologies rstaveley i will have to leave this for tonight....I have gotten more confused as I have gone along.  I will work on getting the program back to where we spoke about and post my response tomorrow..thanks for the help

Kaz
0
 
rstaveleyCommented:
Have a good rest.
0
 
itsmeandnobodyelseConnect With a Mentor Commented:
It's obvious that all strings in the file have been written unproperly to the file. I suppose that the string have been copied by memcpy or strncpy omitting the terminating zero character. Also the BirdRecord struct has not been initialized before writing.

I don't know whether you have influence on the writing part of the file. If so, you should add a constructor to struct BirdRecord that makes all zero at constructing time:


struct BirdRecord          //define a BirdRecord struct
     {
     int reference;//to store the key
     int firstDate;//date variable store date 1st sighting
     int firstMonth;
     int firstYear;
     int latestDate;
     int latestMonth;
     int latestYear;
     char type[BIRD_SIZE];//constant int defined in const.h
     char location[LOCATION_SIZE];//date variable store date last sighting
     //constant int defined in const.h
     int numberOfBirds;
   
     BirdRecord() { memset(this, 0, sizeof(BirdRecord)); }
     };

Also when copying strings to BirdRecord it should be done like that:

   BirdRecord bird;   // now all is zero because of constructor

   ...

   strcpy(bird.type, BIRD_TYPE[2]);  // copying "black ducks" including terminating zero character


With that, you would read strings properly terminated and not something like

         whistling ducksÌÌÌÌAwonga...



rstaveleys approach now is to accept that data is corrupt but try to read valid data anyhow. That can be done as you 'know' all valid string values. So you can make a left compare of the input string (e. g. birds.type ) and all valid strings. That will work as long as there are no two valid values of different length where the shorter one is a leftside substring of the longer one. And even that could be handled by sorting all valid string values by length in descending order.

Regards, Alex







0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.