tags:

views:

1084

answers:

4

So i have a class object type, myClass classType as a global. whats not happeing is that would prefer to have

// MyClass.h
{
  private:
    char FirstName;
    char LastName;
    char MiddleName;
    int ID;
    int Age;
};

// Globals
const int myIndex = 256;
myClass classType[ myIndex ];

int main()
{

   // assume preprocessors are included

   cout << "Enter File: ";
   cin  >> cArray;
   if ( !inFile.good() ) 
   {
     cout << "Wrong?" << endl;
   }
   inFile.open( cArray );
   while ( !inFile.eof() )
   {
     linecount++ // giving me 1 and not counting the file lines

 inFile.read( ( char * ) &myType[linecount], sizeof( myClass ) );

   }
}

Thats a rough idea of what main looks like for me today. I have yet to use myClass.cpp at all! My Text file is of this format:

FirstName LastName ID Number Age ...

After debugging, i notice that the newline character was not detected and now everything is BUNCHED in, on the same index! Like my Increment didnt work or something..

I wanted to increment for however many lines their are in the file. ( more than one ) Im trying to fix the linecount ( idx ) in hopes of fully resolving this issue.

My Private members, FirstName LastName, and so on as i wrote above are present when debugging and dragging on the myclasstype. I just Need to get them with their proper varaible. I just hope the ifstream::read() function is not leading me in a bad direction.

Any Suggestions?

A: 
  • I've recommended the use of boost::serialization for the same goals.
  • Why do you increment linecount before reading a line? You leave the first element of myType uninitialized.
  • If you're using a text file format, why are you using the read function?
bb
A: 

Several points;

  • what is cArray?
  • you must test that the file opened using is_open()
  • the eof() function will only detect end of file AFTER you have read something
  • you should be using std::getline() to read lines
  • as was pointed out in a comment, the names in your class are single chars, they should be std::strings
anon
A: 

You approach with read(buf, size) won't work if your data comes from a textfile. It will fill buf with whatever bytes are read from the input. You can't "fill" an object somewhere in memory that way. read(buf, size) works only with binary data.

I would overload the stream operator >> to do the actual parsing of the textdata. The output will be stored in the object passed as a reference:

istream& operator>> (istream& in, MyClass& val );

Jens
+1  A: 
// MyClass.h
{
  private:
    char FirstName;
    char LastName;
    char MiddleName;
    int ID;
    int Age;
};

What is this struct/class? I guess that it is myClass. Anyway myClass is not meaningful name.

  1. FirstName/LastName/MiddleName eighter are initials - which means that the name is wrong - or are badly typed. What you are looking for is eighter std::string or char *.
  2. Traditionally ID is the first field - if it is needed.

``

// Globals
const int myIndex = 256;
myClass classType[ myIndex ];

As a rule of thumb - never use globals. You will have probles.

int main()
{

   // assume preprocessors are included

   cout << "Enter File: ";
   cin  >> cArray;

What is cArray?

   if ( !inFile.good() )

Where is inFile defined? Why do you check IO state before any IO operation on this stream?

   {
     cout << "Wrong?" << endl;
   }
   inFile.open( cArray );

Well. Isn't simpler to write ifstream inFile(cArray)?

while ( !inFile.eof() ) { linecount++ // giving me 1 and not counting the file lines

You ask for overflow. What if file have more the 256 lines? What worst program will not crash - it will likely write in some unspecifed place.

 inFile.read( ( char * ) &myType[linecount], sizeof( myClass ) );
  1. Never use binary formats unless you have to. They are very hard to debug. If you have a nice, simple text format all you need to test is a text editor to edit test input files. With binary you have no guarantee that the bug is in the program not in the test case.
  2. Evern if you do use binary format do not read it this way. In fact you have no way to determine if the compiler haven't changed the offsets. For example ID will have usually an offset of 4 bytes. But compiler is free to optimize it.

    Additionaly you have no way of determine the size of ID and Age except they are bigger then 2 bytes. They usually are 4, but on some 64-bits compilers (IMHO such way is correct where int == single word) thay may be 8. In the future thay may be 16 (if there will be 128-bit computers). You may think there never be but at the same way "768 K was enought for everybody" (that was a lot those days).

If you try to read text in such way

   }
}

Unless you need to validate the input (in such case iostreams is not the best tool):

class person
{
public:
  person (const std::string &first_name,
          const std::string &last_name,
          const std::string &middle_name,
          int                id,
          int                age)
          : m_first_name(first_name),
            m_last_name(last_name),
            m_middle_name(middle_name,
            m_id(id),
            m_age(age) {}
private:
  std::string m_first_name, m_last_name, m_middle_name;
  int m_id, m_age;
};
// Lots of other code
std::vector<person> people;
while(...)
  {
    std::string first_name, last_name, middle_name;
    int id, age;
    in_file >> first_name >> last_name >> middle_name >> id >> age;
    person p(first_name, last_name, middle_name, id, age);
    people.push_back(p);
  }

It can be shorten and it have to be fill but: 1. Use nice C++ features such as STL (you don't have to remember index or you don't have to worry about vector overflow) 2. It uses text format

Maciej Piechotka