Concontanating unsigned short variables

Last Edited By Krjb Donovan
Last Updated: Mar 12, 2014 02:46 PM GMT

Question

QUESTION: Hi, I am developing a code to write 64 bits into a binary file. These 64 bits are divided into 5 fields of 14, 15, 5, 6, 24 bits. The values of 5 fields are to be received from user, hence I developed a program to receive these 5 fields into 5 unsigned short integers (except 1 long int).Thus, I received 12 bytes. Now, I have to concatenate these integers to form a structure of 64 bits. How can I do this? which data type should I use to hold these 64 bits for shift operations.

Thanx. -Abhijeet.

ANSWER: Hmm, you do not mention if your compiler supports a 64-bit integer type -long long or __int64 (or more likely their unsigned counterparts) or some such.

If it does then you could bitwise or and shift left values into such a 64 bit integer. So assuming the 14 bit field occupies the most significant portion of the 64-bit value and the 24 bit field the least significant portion then you could do something like so:

   unsigned long long valueOf64Bits( field14 );
   valueOf64Bits <<= 15;
   valueOf64Bits |= field15;
   valueOf64Bits <<= 5;
   valueOf64Bits |= field5;
   valueOf64Bits <<= 6;
   valueOf64Bits |= field6;
   valueOf64Bits <<= 24;
   valueOf64Bits |= field24;

If your compiler does not support 64 bit types then you can use say two 32-bit values instead. in this case you would have to split the 5 bit field value into two: a 3 and a 2 bit field as this field straddles the two 32-bit portions of the 64 bit value:

   field3 = (field5 & 0x1c) >> 2;
   field2 = field5 & 3;

Then start with the 1st unsigned 32 bit integer (unsigned long ?) and proceed as above for field14 and field15 for the new variable instead of valueOf64Bits, then for the remaining 3 bits use field3:

   highValueOf32Bits <<= 3;
   highValueOf32Bits |= field3;

The for the lower 32 bits start with the value of field2:

   unsigned long lowValueOf32Bits( field2 );

Then proceed for lowValueOf32Bits as for valueOf64Bits above for the field6 and field24 parts.

However C and C++ support a feature called bit fields that allows allocation of fields of bits of specified widths within an underlying integer type value. With this feature you could split a 64-bit integer base value field of a a struct or class into sub-fields of the bit widths you specify directly, for example:

   struct SubFieldsOf64Bits
   {
       unsigned long long field24:24;
       unsigned long long field6:6;
       unsigned long long field5:5;
       unsigned long long field15:15;
       unsigned long long field14:14;
   };

Note however that there are a lot of uses of the term 'implementation dependent' in the ISO C++ standard wording for bit fields. Two things that may effect you here are that it is up to the compiler implementation which way into the underlying value the bits fields are allocated: left to right or right to left and whether bit fields will straddle allocation units (which I take to mean individual words of the underlying type) or not. This last may be an issue if you do not have a 64 bit integer type and wish to use 2 32 bit words instead.

I used the above struct with Microsoft Visual C++ 2008 32 bit and GNU g++ 4.4.1 64-bit x86 compilers, and the layout is consistent with that assumed by the original shift-and-or example - i.e. that the 14 bit field is the highest 14 bits and the 24 bit field the lowest.

We can combine such a bit field struct with a union, for example:

   union RepresentationsOf64Bits
   {
       unsigned long long all64bits;
       unsigned int       hiLo32bits[2];
       SubFieldsOf64Bits  fields;   
   };

(note the 32-bit integer type used is unsigned int as on the 64 bit GNU compiler unsigned long is 64 bits in size)

Which can be used like so (following on from my original example):

   RepresentationsOf64Bits  a64BitValue;
   a64BitValue.all64bits = valueOf64Bits;
   RepresentationsOf64Bits  another64BitValue;
   another64BitValue.fields.field14 = field14;
   another64BitValue.fields.field15 = field15;
   another64BitValue.fields.field5 = field5;
   another64BitValue.fields.field6 = field6;
   another64BitValue.fields.field24 = field24;

And we could display the results like so:

   std::cout <<   "field14 = 0x" << std::hex << field14
             << "\nfield15 = 0x" << std::hex << field15
             << "\n field5 = 0x" << std::hex << field5
             << "\n field5 = 0x" << std::hex << field6
             << "\nfield24 = 0x" << std::hex << field24
             << "\n 64-bit = 0x" << std::hex << valueOf64Bits
             << "\n\n Set 64-bit check 32 and fields"
             <<   "\n-------------------------------"
             << "\n 64-bit = 0x" << std::hex << a64BitValue.all64bits
             << "\nfield14 = 0x" << std::hex << a64BitValue.fields.field14
             << "\nfield15 = 0x" << std::hex << a64BitValue.fields.field15
             << "\n field5 = 0x" << std::hex << a64BitValue.fields.field5
             << "\n field5 = 0x" << std::hex << a64BitValue.fields.field6
             << "\nfield24 = 0x" << std::hex << a64BitValue.fields.field24
             << "\nHi32-bits=0x" << std::hex << a64BitValue.hiLo32bits[1]
             << "\nLo32-bits=0x" << std::hex << a64BitValue.hiLo32bits[0]
             << "\n\n Set fields check 64 and 32 bit"
             <<   "\n-------------------------------"
             << "\nfield14 = 0x" << std::hex << another64BitValue.fields.field14
             << "\nfield15 = 0x" << std::hex << another64BitValue.fields.field15
             << "\n field5 = 0x" << std::hex << another64BitValue.fields.field5
             << "\n field5 = 0x" << std::hex << another64BitValue.fields.field6
             << "\nfield24 = 0x" << std::hex << another64BitValue.fields.field24
             << "\n 64-bit = 0x" << std::hex << another64BitValue.all64bits
             << "\nHi32-bits=0x" << std::hex << another64BitValue.hiLo32bits[1]
             << "\nLo32-bits=0x" << std::hex << another64BitValue.hiLo32bits[0]
             << std::endl;

If all is OK then the 64-bit and field values for each section should be the same and the hi and lo 32-values should match the upper and lower portions of the 64-bit values, like so:

   field14 = 0x364d
   field15 = 0x6c67
    field5 = 0xf
    field6 = 0x36
   field24 = 0x19727a
    64-bit = 0xd937633bf619727a
    Set 64-bit check 32 and fields
   -------------------------------
    64-bit = 0xd937633bf619727a
   field14 = 0x364d
   field15 = 0x6c67
    field5 = 0xf
    field6 = 0x36
   field24 = 0x19727a
   Hi32-bits=0xd937633b
   Lo32-bits=0xf619727a
    Set fields check 64 and 32 bit
   -------------------------------
   field14 = 0x364d
   field15 = 0x6c67
    field5 = 0xf
    field6 = 0x36
   field24 = 0x19727a
    64-bit = 0xd937633bf619727a
   Hi32-bits=0xd937633b
   Lo32-bits=0xf619727a

Note that I am randomly creating field values of the required bit width for field14, field15, field5, field6 and field24.

If you are allocating the bit fields within the 64-bit word in the opposite order then reverse the order of fields - and be careful if you have to split field5 to get the bits allocated to the correct word.

Oh and if your compiler supports it or you have a 3rd party implementation available then you might like to use the typedefs in the cstdint (or C header file stdint.h) such as uint16, uint32 and uint64 - if supported (these typedefs are marked as optional in the current draft of the next C++ standard, and in the C1999 standard).

Hope this helps


---------- FOLLOW-UP ----------

QUESTION: Thanx a lot. But I need to get the values, that has to be stored in these variables from user through console input, and it is showing error if I tried to get the values of these bit fields through console. The error message says, 'accessing the address of bit fields is illegal'. Can I get the values of bit fields directly through console?

ANSWER: If by:

   "Can I get the values of bit fields directly through console?"

you mean:

   "Can I get the values read from the console directly into bit field data members of an object?"
   

then in short no.

Oh, and this seems to be a change in the stated requirements. As you will note my examples show the 5 field values (from where ever) already set up and are of the types you stated in your original question (all unsigned short except field24 which was unsigned long as per your question text). In your case 'where ever' would be from the console.

You cannot access bit fields directly by address because they are sub-parts of the underlying integer type and would not fall on an addressable boundary and fill an exact multiple of addressable units in most cases even if the addressable unit of the processor is smaller than that of the underlying integer containing the bit fields. This is the case here for most of your fields on a byte addressed machine (as is common for modern processors). In order to perform assignment from an integer to a bit field (or the other way around) I would expect the compiler to generate code to perform bitwise Boolean operations and shifting operations similar to those in the first part of my previous answer. Note that non-const references to bit fields are also forbidden.However this implies that references to const bit fields are allowed so in the case for (const) references to bitfields the compiler converts the bitfield to a temporary integer value of the underlying integer type and returns a const reference bound to the temporary value.

What is happening is that the input stream operator needs to dump data - that which has been read from the console presumably - into the location of the receiving object. To do this of course it requires the address of the object into which to write the read data. As you have given it a bit field it cannot obtain the address, as this is forbidden by C and C++ for the reasons stated in the previous paragraph.

So read the fields into intermediate integers and assign these to the bit fields.

   RepresentationsOf64Bits  a64BitValue;
   unsigned long aField(0);
   std::cin >> aField;
   // check read successful and read value is valid etc. ...
   a64BitValue.fields.field14 = aField;
   std::cin >> aField;
   // check read successful and read value is valid etc. ...
   a64BitValue.fields.field15 = aField;
                   .
                   .
                   .

For reference, the text of the paragraph in the C++ standard on bitfields stating that there are no pointers to bitfields is Section 9.6 Bit Fields paragraph 3 and read as follows:

   "A bitfield shall not be a static member. A bitfield shall have integral or
    enumeration type (3.9.1). It is implementation defined whether a plain
    (neither explicitly signed nor unsigned) char, short, int or long bitfield
    is signed or unsigned. A bool value can successfully be stored in a bitfield
    of any nonzero size. The addressof operator & shall not be applied to a
    bitfield, so there are no pointers to bitfields. A non-const reference shall
    not be bound to a bitfield (8.5.3). [Note: if the initializer for a
    reference of type const T& is an lvalue that refers to a bitfield, the
    reference is bound to a temporary initialized to hold the value of the
    bitfield; the reference is not bound to the bitfield directly. See 8.5.3. ]"

To help you get some idea of the difference between assigning between 'whole' integer objects and data members and 'part' integer bit field data members I show below the AMD x84 assembler of two of the lines from my original example as generated by the Visual Studio 2008 AMD x64 compiler. First assigning directly to the all64bits unsigned long long 'whole' integer data member of a RepresentationsOf64Bits object:

   ; 93   :         a64BitValue.all64bits = valueOf64Bits;
       mov rax, QWORD PTR valueOf64Bits$[rsp]
       mov QWORD PTR a64BitValue$[rsp], rax

Which just moves the 64 bit unsigned long long value to be assigned into the rax 64-bit register and then writes it directly into the memory location(s) for the RepresentationsOf64Bits a64BitValue object's all64bits (which is at offset zero, and relative to the stack pointer as it is on the stack frame of the function call).

Next assigning to the field14 bit field of the fields member of the RepresentationsOf64Bits union from the field14 unsigned short:

   ; 96   :         another64BitValue.fields.field14 = field14;
       movzx   edx, WORD PTR field14$[rsp]
       and rdx, 16383              ; 00003fffH
       shl rdx, 50                 ; 00000032H
       mov rcx, 1125899906842623           ; 0003ffffffffffffH
       mov rax, QWORD PTR another64BitValue$[rsp]
       and rax, rcx
       or  rax, rdx
       mov QWORD PTR another64BitValue$[rsp], rax

First the field14 value is loaded (effectively) into the rdx 64 bit register. Next it is 'trimmed' to 14 bits (the and instruction performing a masking operation) and shifted up to the correct part of the 64-bit word.

Next another mask value is loaded into the 64 bit rcx register which has one for all bits that are _not_ part of the field14 bit field of the 64 bit value, and this is used with an and instruction (again) to clear the existing value of the field14 bits to all zero bit values. The new field14 value and the other bit fields are then combined (the or instruction) and finally the updated whole 64 bit value in rax is written to the fields member of the another64BitValue RepresentationsOf64Bits union object (which because it is a union is also at an offset zero).


The point to take away is that bit fields work on the whole of the underlying integer they are bit fields of and it is these whole integers that are written to and read from memory. Hence the bit fields themselves are not really considered as whole objects having separate addresses.


---------- FOLLOW-UP ----------

QUESTION: I want to use DevC++ instead of turboC++ following is my code in turboC++

  1. include<fstream>

using namespace std;

  1. include<iostream>

using namespace std; //using namespace std;

  1. include<conio.h>
  2. include<stdlib.h>
  3. include<string.h>
  4. include<iomanip.h>
  5. include<stdio.h>
  6. include<limits.h>
  7. include<windows.h>


  1. define BITMASK(b) (1 << ((b) % 32))
  2. define BITSLOT(b) ((b) / 32)
  3. define BITSET(a, b) ( (a) [BITSLOT(b)] |= BITMASK(b) )
  4. define BITCLEAR(a, b) ( (a) [BITSLOT(b)] &= ~BITMASK(b) )
  5. define BITTEST(a,b) ( (a)[BITSLOT(b)] & BITMASK(b) )
  6. define BITNSLOTS(nb) ((nb + 32 - 1) / 32)

void clrscr() { system("cls");

	}  
	

void gotoxy(int x, int y)

{ HANDLE hConsoleOutput; COORD dwCursorPosition; cout.flush(); dwCursorPosition.X = x; dwCursorPosition.Y = y; hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition); } /*void gotoxy(int x, int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_H ANDLE), coord); }*/

struct teds_data { unsigned short Man_id; unsigned short Mod_no; unsigned char Ver_ltr; unsigned short Ver_no; unsigned long Ser_no; unsigned short Selctr; unsigned short Templ_id;

}p;

class group

    {
    private:int age;

float sal;


public: group(); // void copy();


void man_id(); void mod_no(); void ver_ltr(); void ver_no(); void ser_no(); void selctr(); void templ_id(); // void exit();

};

group::group()

{ofstream outfile; outfile.open("WR_TEDs.DAT", ios::binary|ios::out); if(!outfile) { cout<<endl<<"unable to open "; outfile.close(); //exit(); getch(); } }

/* void create() {ofstream outfile; outfile.open("TEDs.DAT", ios::binary|ios::out); if(!outfile) { cout<<endl<<"unable to open"; outfile.close(); //exit(); } else { // outfile.open("TEDs.DAT",ios::binary|ios::out); outfile.write((char*)&p, sizeof(p)); outfile.close(); } // exit();

};

  • /

/* void group::copy() { group(); file.write("EMP.DAT", p) ; }

  • /

int main() { struct w_teds { unsigned long int MSB64Bits; unsigned long int LSB64Bits; }w; struct w_teds r; unsigned long int field1, field3,fieldr1,fieldr3; // unsigned short i; char field2,fieldr2; //valueOf64Bits=12345123456789; clrscr(); // cout<<"array64Bits = "<<array64Bits[2]<<endl; cout<<"size of struct w= "<<sizeof(w)<<endl <<"size of struct p ="<<sizeof(p); getch();

struct teds_data { unsigned short Man_id; unsigned short Mod_no; unsigned char Ver_ltr; unsigned short Ver_no; unsigned long Ser_no; unsigned short Selctr; unsigned short Templ_id;

}t; /*char bitarray[BITNSLOTS(47)]; BITSET(bitarray, 23); clrscr();

if(BITTEST(bitarray,23))

{ cout<<"bit 23 is set"; } getch(); //struct teds_data * tedptr; //tedptr = &p; */ char choice,selection;

group g;

do
{
clrscr();
gotoxy(25,27);
cout<<"Enter '0' for EXIT";
gotoxy(25,25);
cout<<"Enter '1' for READING TEDs";
gotoxy(25,26);
cout<<"Enter '2' for WRITING TEDs";
gotoxy(25,28);
cout<<"Your selection : ";
cin>>selection;
   switch(selection)
   {
       case 1:
    ofstream file;
    file.open("RD_TEDs.DAT", ios::binary|ios::in|ios::out);
    clrscr();
    gotoxy(25,25);
    if(!file)

{ cout<<endl<<"unable to open file"; file.close(); }

else { file.close(); file.open("RD_TEDs.DAT", ios::binary|ios::in);

while( file.read((char*)&r, sizeof(r))) { cout<<"o/p: MSB: "<<r.MSB64Bits<<"LSB :"<<r.LSB64Bits; getch(); }

if(r.MSB64Bits!=0 && r.LSB64Bits!=0) { fieldr1=r.MSB64Bits; fieldr1=fieldr1>>18; t.Man_id=fieldr1;

fieldr1=r.MSB64Bits; fieldr1=fieldr1>>3; fieldr1=fieldr1 & 32767; t.Mod_no=fieldr1;

fieldr1=r.MSB64Bits; fieldr1=fieldr1<<29; fieldr1=fieldr1>>27; fieldr3=r.LSB64Bits; fieldr3=fieldr3>>30; fieldr2=fieldr1+fieldr3+64; t.Ver_ltr=fieldr2;

fieldr3=r.LSB64Bits; fieldr3=fieldr3<<2; fieldr3=fieldr3>>26; t.Ver_no=fieldr3;

fieldr3=r.LSB64Bits; fieldr3=fieldr3<<8; fieldr3=fieldr3>>8; t.Ser_no=fieldr3;

clrscr(); gotoxy(25,24); cout<<"Manufacturer ID = "<<t.Man_id; gotoxy(25,25); cout<<"Model number = "<<t.Mod_no; gotoxy(25,26); cout<<"Version letter = "<<t.Ver_ltr; gotoxy(25,27); cout<<"Version number = "<<t.Ver_no; gotoxy(25,28); cout<<"Serial number = "<<t.Ser_no; getch(); } else { cout<<"r.MSB64Bits==0 && r.LSB64Bits==0"; getch(); } file.close(); }

   break;

   case 2:

do { clrscr(); gotoxy(25,30); cout<<"Enter '0' for 'exit'"; // gotoxy(25,22); // cout<<"Enter '1' for 'creating new file'"; gotoxy(25,23); cout<<"Enter '1' for 'manufacturer id'"; gotoxy(25,24); cout<<"Enter '2' for 'model number'"; gotoxy(25,25); cout<<"Enter '3' for 'version letter'"; gotoxy(25,26); cout<<"Enter '4' for 'version number'"; gotoxy(25,27); cout<<"Enter '5' for 'serial number'"; gotoxy(25,28); cout<<"Enter '6' for 'selector'"; gotoxy(25,29); cout<<"Enter '7' for 'templet id'"; gotoxy(25,31); cout<<"Your choice : "; cin>>choice; clrscr();

switch(choice) { // case '1': // g.create(); // break; case '1': g.man_id(); break; case '2': g.mod_no(); break; case '3': g.ver_ltr(); break; case '4': g.ver_no(); break; case '5': g.ser_no(); break; case '6': g.selctr(); break; case '7': g.templ_id(); break; } }while(choice!='0');

field1=p.Man_id; field1=field1<<15; w.MSB64Bits=field1+p.Mod_no; field1=w.MSB64Bits; field1=field1<<3; field2=p.Ver_ltr>>2; field1=field1+field2; w.MSB64Bits=field1; cout<<endl<<" array64Bits[1] = "<<w.MSB64Bits<<" / "<<(int)p.Ver_ltr; getch(); field2=p.Ver_ltr<<6; field2=field2>>6; field3=(unsigned long int)field2; field3=field3<<6; field3=field3+p.Ver_no; field3=field3<<24; field3=field3+p.Ser_no; w.LSB64Bits=field3; cout<<endl<<" array64Bits[2] = "<<w.LSB64Bits<<" / "<<(int)p.Ver_ltr; getch(); ofstream outfile; outfile.open("WR_TEDs.DAT", ios::binary|ios::out); if(!outfile) { cout<<endl<<"unable to open outfile"; outfile.close(); getch(); } else { // outfile.open("TEDsreadwrite.DAT",ios::binary|ios::out); outfile.write((char*)&w, sizeof(w)); outfile.close(); }

   break;


   }
}while(selection!='0');

remove("RD_TEDs.DAT"); fstream file;

    file.open("RD_TEDs.DAT", ios::binary|ios::in|ios::out);
    if(!file)

{clrscr(); gotoxy(25,25); cout<<endl<<"unable to create RD_TEDs file"; getch(); file.close(); }

    else
    file.close();

//p.Man_id=p.Man_id<<2;

// i=0; /* while(!BITTEST(array64Bits,i)) {i++; cout<<"bit is set"; } cout<<"bit is set "<<i; getch();

  • /

}

/* void group::exit() { outfile.close(); }; */

void group::man_id() { unsigned short l; clrscr(); gotoxy(25,25); cout<<"Enter manufacturer id: "; cin>>p.Man_id; while(p.Man_id<17 || p.Man_id>16384) {clrscr(); gotoxy(25,25); cout<<"Enter proper manufacturer id again: "; cin>>p.Man_id; }; // clrscr(); gotoxy(25,26); cout<<"manufacturer id= "<<p.Man_id; // l=p.Man_id<<3; // cout<<l<<" 'press Enter'"; // cout<<"size of teds_data= "<<sizeof(teds_data); getch(); };

void group::mod_no() { clrscr(); gotoxy(25,25); cout<<"Enter 'model number': "; cin>>p.Mod_no; while(p.Mod_no>32767) {clrscr(); gotoxy(25,25); cout<<"Enter proper 'model number' again: "; cin>>p.Mod_no; }; // clrscr(); gotoxy(25,26); cout<<"model number= "<<p.Mod_no; cout<<" 'press Enter' "; getch(); };

void group::ver_ltr() { char ltr; clrscr(); gotoxy(25,25); cout<<"Enter 'version letter'from 'A' to 'Z': "; cin>>ltr; while(ltr>90 || ltr<65) {clrscr(); gotoxy(25,25); cout<<"Enter proper 'version letter' from 'A' to 'Z' again: "; cin>>ltr; }; // clrscr(); gotoxy(25,26); cout<<"version letter= "<<ltr; cout<<" 'press Enter' "; ltr=ltr & 31; p.Ver_ltr=ltr; getch(); };

void group::ver_no() { clrscr(); gotoxy(25,25); cout<<"Enter 'version number': "; cin>>p.Ver_no; while( p.Ver_no>63) {clrscr(); gotoxy(25,25); cout<<"Enter proper 'version number' again: "; cin>>p.Ver_no; }; // clrscr(); gotoxy(25,26); cout<<"version number= "<<p.Ver_no; cout<<" 'press Enter' "; getch(); };

void group::ser_no() { clrscr(); gotoxy(25,25); cout<<"Enter 'serial number': "; cin>>p.Ser_no; while(p.Ser_no>16777215) {clrscr(); gotoxy(25,25); cout<<"Enter proper 'serial number' again: "; cin>>p.Ser_no; }; // clrscr(); gotoxy(25,26); cout<<"serial number= "<<p.Ser_no; cout<<" 'press Enter' "; getch(); };

void group::selctr() { clrscr(); gotoxy(25,25); cout<<"Enter 'selector number': "; cin>>p.Selctr; while( p.Selctr>3) {clrscr(); gotoxy(25,25); cout<<"Enter proper 'selector number' again: "; cin>>p.Selctr; }; // clrscr(); gotoxy(25,26); cout<<"selector number= "<<p.Selctr; cout<<" 'press Enter' "; getch(); };

void group::templ_id() { clrscr(); gotoxy(25,25); cout<<"Enter 'template id': "; cin>>p.Templ_id; while(p.Templ_id>255) {clrscr(); gotoxy(25,25); cout<<"Enter proper 'template id' again: "; cin>>p.Templ_id; }; // clrscr(); gotoxy(25,26); cout<<"template id = "<<p.Templ_id; cout<<" 'press Enter' "; getch(); };

It works very well in turboC++. While I use DevC++ it shows the following errors: 1. "crosses initialization of `std::ofstream file' " 2. "jump to case label " 3. " ` read' undeclared (first use this function) "

I have searched much on net, but didn't get any solution. Please, tell me where I'm wrong and what to do in order to run the code.

Answer

OK errors 2 and 1 are the same problem probably:

   jump to case label
       crosses initialization of `std::ofstream file'

Note the indentation. It is because the file stream object is _not_ initialised by all following case and default labels in the switch, and so the file object can be accessed in code following its declaration with out being initialised - because the switch jumped around it!

Fix: wrap the whole of the case handling code in { and } so file is local to this block:

       case 1:
           {
               ofstream file;
           ...
           }
           break;

As to 3. Not sure (see notes below). Which use of read was the error referring to? I could only locate one. If it is the one associated with file then do output file streams (i.e. std::ofstream) support such an operation? (remember output implies writing and putting to a file). To get input and output file operation we would use a .... yes std::fstream object.

Oh and some other notes on your code are that you seem to be using pre-standard C++ library headers for some headers and not others: pre-standard <iomanip.h> rather than <iomanip>, but standard <iostream> and <fstream> also the C library headers have standard C++ library equivalents with no .h suffix and a c prefix: <cstring> rather than <string.h> for example. The using namespace std directive, if present at all, should be after _all_ header file includes and using directives should _never_ be placed in header files - see http://www.gotw.ca/gotw/053.htm, especially the material about third of the way down under "Characteristics of a Good Long-Term Solution").

There is a _lot_ of other things I could say but I do not have the time and are not really pertinent to your question.

Now some points about your question:

First standard whinge about posting large amounts of code - please do not. Please reduce the code to the minimum possible to demonstrate the problems. You might find in doing so you fix the problems yourself.

Second, why do you post your code even with what appears to be a lot of commented out unused portions. Please post only "live" code - I do not need to see commented out parts. Doing so only obfuscates your code even more and makes it that much harder to get my head around what you are doing.

Third, your code is completely uncommented and the formatting looks to be all over the place. Your question gives no hint of what it is trying to achieve. If you want people to help you then take the time to acquaint them with your code and make it pleasant and easy for them to read. (OK it may be that your code is formatted beautifully but posting through AllExperts messed it up...)

Forth, you have shown me the errors - do you think it would be useful to _also_ point me to the lines of code they refer to? After all you have this information I do not so have to try to work it out for myself (and am not sure I have for your third error for example).

Fifth - it would have been useful if you mention versions of the tools, operating systems, additional libraries etc. you are using - especially in this case that of Turbo C++ which has been around in various versions for decades (see http://en.wikipedia.org/wiki/Turbo_C%2B%2B for a brief history).

I will reject any future questions you post if you have not appeared to have taken note of the points made above.

Advertisement

©2017 eLuminary LLC. All rights reserved.