Thread: Need help with C++ file operations program!

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    5

    Need help with C++ file operations program!

    Hi,

    I have a big problem with my program..I have not completed all its functions but the ones I have included the whole program below..the program is basically an employee payroll program which has 2 files, 1 which holds staff details such as employee name and number,address etc. The other file holds that employee's corresponding salary details such as allowances and deductions for tax etc. Both the structures have 3 elemnts common to both. The thing is, I'm not even sure the file is being written into, I have a display function which is supposed to display an employee's details when the user enters his employee number..ANY help is appreciated!

    Code:
    #include<fstream.h>
    #include<conio.h>
    #include<math.h>
    #include<stdio.h>
    #include<dos.h>
    #include<process.h>
    
    //GLOBAL VARIABLES..........................................................................................................
    int n;//global variable n to store number of records
    
    //FUNCTION PROTOTYPES.......................................................................................................
    void main();
    void append();
    void display();
    void modify();
    
    //STRUCTURES FOR STAFF FILE AND STAFF SALARY FILE...........................................................................
    //Staff structure
    struct staff
    {
    int empno;
    char na[20];
    char add[20];
    long tp;
    int dj;
    int dd;
    char desig[20];
    char dept[20];
    long double bsal;
    }z;
    
    //Salary structure
    struct sal
    {
    int empno;
    long double bsal;
    long double da;
    long double hra;
    long double ca;
    long double medical;
    long double pf;
    long double itax;
    long double gsal;
    long double netsal;
    }y;
    
    
    //FUNCTIONS.................................................................................................................
    
    //MAIN FUNCTIONS(TO BE LOADED FROM MAIN FUNCTION)
    //Create file function to enter records for both salary and staff files
    void create()
    {
    clrscr();
    long count;//variable used to time delay loop
    cout<<"\nHow many records do you wish to create?\n";
    cin>>n;
    ofstream f1,f2;
    f1.open("staff.dat",ios::out|ios::binary);
    f2.open("salary.dat",ios::out|ios::binary);
    for(int i=0;i<n;i++)
    {
    cout<<"\nEnter employee number\n";
    cin>>z.empno;
    cout<<"Enter name of employee\n";
    gets(z.na);
    cout<<"Enter Phone number of employee\n";
    cin>>z.tp;
    cout<<"Enter address of employee\n";
    gets(z.add);
    cout<<"Enter date of joining of employee\n";
    cin>>z.dj;
    cout<<"Enter date of birth of employee\n";
    cin>>z.dd;
    cout<<"Enter designation of employee\n";
    gets(z.desig);
    cout<<"Enter department\n";
    gets(z.dept);
    cout<<"Enter basic salary\n";
    cin>>z.bsal;
    cout<<"\nWriting Staff file.....\n";
    f1.write((char*)&z,sizeof(z));
    cout<<"\nFile successfully created!\n";
    cout<<"\n\nEnter information for Staff Salary file\n";
    cout<<"Enter medical allowance\n";
    cin>>y.medical;
    y.empno=z.empno;
    y.bsal=z.bsal;
    y.hra=z.bsal*0.15;
    y.da=z.bsal*0.3;
    y.pf=z.bsal*0.08;
    y.ca=z.bsal*0.1;
    y.gsal=z.bsal+y.da+y.hra+y.ca;
    y.itax=y.gsal*0.3;
    y.netsal=y.gsal-(y.pf+y.itax);
    f2.write((char*)&y,sizeof(y));
    cout<<"\nWriting Staff salary file\n";
    cout<<"File successfully created!\n";
    }
    cout<<"Returning to Main menu.......\n";
    f1,f2.close();
    for(count=0;count<=90000;count++);
    main();
    }//create()
    
    //SUB FUNCTIONS(WITHIN MENUS).................................................
    
    //STAFF FILE FUNCTIONS........................................................
    //Display the staff menu with corresponding functions
    void staff()
    {
    clrscr();
    cout<<"\nSTAFF MENU\n";
    cout<<"==========\n";
    cout<<"1.APPEND N NUMBER OF RECORDS\n";
    cout<<"2.DISPLAY AN EMPLOYEE'S RECORD\n";
    cout<<"3.MODIFY AN EMPLOYEE'S RECORD\n";
    int choice;
    cout<<"Enter choice\n";
    cin>>choice;
    switch(choice)
    {
    case 1:cout<<"\nAPPEND FUNCTION\n";
           append();
           break;
    case 2:cout<<"\nDISPLAY RECORD\n";
           display();
           break;
    case 3:cout<<"\nMODIFY THE RECORD OF AN EMPLOYEE\n";
           modify();
           break;
    default:cout<<"\nWrong choice entered!Returning to main menu...\n";
    	main();
    	break;
    }//switch
    }//staff function
    
    //Append function to append records to staff and salary files
    void append()
    {
    clrscr();
    ofstream f1,f2;
    int i;
    long count;
    f1.open("staff.dat",ios::out|ios::app);
    f2.open("salary.dat",ios::out|ios::app);
    int no;
    cout<<"\n\t\tAPPEND FUNCTION\n";
    cout<<"\t\t===============\n";
    cout<<"Enter number of records to be appended\n";
    cin>>no;
    for(i=0;i<no;i++)
    {
    cout<<"\nEnter employee number\n";
    cin>>z.empno;
    cout<<"Enter name of employee\n";
    gets(z.na);
    cout<<"Enter Phone number of employee\n";
    cin>>z.tp;
    cout<<"Enter address of employee\n";
    gets(z.add);
    cout<<"Enter date of joining of employee\n";
    cin>>z.dj;
    cout<<"Enter date of birth of employee\n";
    cin>>z.dd;
    cout<<"Enter designation of employee\n";
    gets(z.desig);
    cout<<"Enter department\n";
    gets(z.dept);
    cout<<"Enter basic salary\n";
    cin>>z.bsal;
    cout<<"\nAppending to Staff file.....\n";
    f1.write((char *)&z,sizeof(z));
    cout<<"\nRecord(s) successfully appended!\n";
    cout<<"\n\nEnter information for Staff Salary file\n";
    cout<<"Enter medical allowance\n";
    cin>>y.medical;
    y.empno=z.empno;
    y.bsal=z.bsal;
    y.hra=z.bsal*0.15;
    y.da=z.bsal*0.3;
    y.pf=z.bsal*0.08;
    y.ca=z.bsal*0.1;
    y.gsal=z.bsal+y.da+y.hra+y.ca;
    y.itax=y.gsal*0.3;
    y.netsal=y.gsal-(y.pf+y.itax);
    f2.write((char*)&y,sizeof(y));
    cout<<"\nAppending Staff salary file\n";
    cout<<"Record(s) successfully appended!\n";
    cout<<"Returning to Main menu.......\n";
    }
    f1,f2.close();
    for(count=0;count<=10000;count++);
    for(count=0;count<=10000;count++);
    main();
    }//append
    
    //Display an employee's record according to employee number
    void display()
    {
    clrscr();
    int flag=0;
    int eno;
    int nr;
    cout<<"\n\t\tDISPLAY FUNCTION\n";
    cout<<"\t\t================\n";
    ifstream f1,f2;
    f1.open("staff.dat",ios::in|ios::binary);
    f2.open("salary.dat",ios::in|ios::binary);
    cout<<"\nEnter employee number to be searched for\n";
    cin>>eno;
    f1.read((char*)&z,sizeof(z));
    cout<<z.empno;
    cout<<eno;
    getch();
    while(f1)
    {
    getch();
    if(z.empno==eno)
    {
    float l=f1.tellg();//no of bytes read by f1 stream
    nr=l/sizeof(z);//no of records read
    flag=1;
    break;
    }//if
    f1.read((char*)&z,sizeof(z));
    }//while
    
    if(flag==1)
    {
    f2.seekg(0);
    cout<<"\nEMPLOYEE NUMBER         : "<<z.empno;
    cout<<"\nEMPLOYEE NAME           : "<<z.na;
    cout<<"\nEMPLOYEE ADDRESS        : "<<z.add;
    cout<<"\nTELEPHONE NUMBER        : "<<z.tp;
    cout<<"\nDATE OF JOINING         : "<<z.dj;
    cout<<"\nDATE OF BIRTH           : "<<z.dd;
    cout<<"\nDESIGNATION             : "<<z.desig;
    cout<<"\nDEPARTMENT              : "<<z.dept;
    cout<<"\nBASIC SALARY            : "<<z.bsal;
    cout<<"\nALLOWANCE";
    f2.seekg(nr*sizeof(y));//to get the read pointer to correspoding y location
    cout<<"\nDA                      : "<<y.da;
    cout<<"\nHRA                     : "<<y.hra;
    cout<<"\nCONVEYANCE              : "<<y.ca;
    cout<<"\nMEDICAL                 : "<<y.medical;
    cout<<"\nPROVIDENT FUND          : "<<y.pf;
    cout<<"\nINCOME TAX              : "<<y.itax;
    cout<<"\nGROSS SALARY            : "<<y.gsal;
    cout<<"\nNET SALARY              : "<<y.netsal;
    getch();
    }//if
    else
    cout<<"\nCould not find a matching employee number\n";
    f1,f2.close();
    main();
    }//display
    
    //Modify an employee's record
    void modify()
    {
    cout<<"\n\t\tMODIFY RECORD FUNCTION\n";
    cout<<"\t\t======================\n";
    int rno;
    cout<<"Enter record number to modify\n";
    cin>>rno;
    ofstream f1,f2;
    f1.open("STAFF.JRH",ios::out|ios::binary|ios::ate);
    f2.open("SAL.JRH",ios::out|ios::binary|ios::ate);
    f1.seekp((rno-1)*sizeof(z));
    cout<<"\nEnter employee number\n";
    cin>>z.empno;
    cout<<"Enter name of employee\n";
    gets(z.na);
    cout<<"Enter Phone number of employee\n";
    cin>>z.tp;
    cout<<"Enter address of employee\n";
    gets(z.add);
    cout<<"Enter date of joining of employee\n";
    cin>>z.dj;
    cout<<"Enter date of birth of employee\n";
    cin>>z.dd;
    cout<<"Enter designation of employee\n";
    gets(z.desig);
    cout<<"Enter department\n";
    gets(z.dept);
    cout<<"Enter basic salary\n";
    cin>>z.bsal;
    cout<<"\nModifying Employee Record\n";
    f1.write((char*)&z,sizeof(z));
    cout<<"File successfully modified!\n";
    cout<<"Enter information for Staff Salary file\n";
    cout<<"Enter medical allowance\n";
    cin>>y.medical;
    y.empno=z.empno;
    y.bsal=z.bsal;
    y.hra=z.bsal*0.15;
    y.da=z.bsal*0.3;
    y.pf=z.bsal*0.08;
    y.ca=z.bsal*0.1;
    y.gsal=z.bsal+y.da+y.hra+y.ca;
    y.itax=y.gsal*0.3;
    y.netsal=y.gsal-(y.pf+y.itax);
    f2.write((char*)&y,sizeof(y));
    cout<<"Modifying staff salary of employee\n";
    cout<<"File successfully modified!\n";
    main();
    }//modify
    
    
    //MAIN FUNCTION.............................................................................................................
    void main()
    {
    clrscr();
    int choice;
    cout<<"\nMAIN MENU\n";
    cout<<"=========\n";
    cout<<"1.CREATE FILE\n";
    cout<<"2.STAFF FILE\n";
    cout<<"3.GENERAL REPORT\n";
    cout<<"4.SALARY FILE\n";
    cout<<"5.QUIT\n";
    cout<<"Enter choice\n";
    cin>>choice;
    switch(choice)
    {
    case 1: cout<<"CREATE FILE\n";
    	create();
    	break;
    case 2: cout<<"STAFF FILE\n";
    	staff();
    	break;
    case 3: cout<<"GENERAL REPORT\n";
    
    	break;
    case 4: cout<<"SALARY FILE\n";
    
    	break;
    case 5: cout<<"QUIT\n";
    	exit(0);
    	break;
    default:cout<<"Wrong choice entered...\n";
    	main();
    
    }//switch
    }//main function

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>I'm not even sure the file is being written into
    Open it in Notepad to see what's in it (or a similar text editor).

    Don't use gets(), it's old fashioned C, and shouldn't be anywhere near your C++ program.

    If you're having trouble, break your program down into sections, and work on them one at a time. As you have specific problems/questions, post them here with the sample section of code.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Senior Member joshdick's Avatar
    Join Date
    Nov 2002
    Location
    Phildelphia, PA
    Posts
    1,146
    da, wha, huh,

    Are you trying to call the main() function?!
    Code:
    for(count=0;count<=90000;count++);
    main();
    Don't prototype the main function.

    Don't use void main(). Instead, use int main(), and put return 0; at the end of your main() function.
    FAQ

    "The computer programmer is a creator of universes for which he alone is responsible. Universes of virtually unlimited complexity can be created in the form of computer programs." -- Joseph Weizenbaum.

    "If you cannot grok the overall structure of a program while taking a shower, you are not ready to code it." -- Richard Pattis.

  4. #4
    Registered User
    Join Date
    Oct 2003
    Posts
    5

    Arrow

    Hi, thanks for all the replies, anyway, I tried opening the files in notepad earlier, however, 1 file has a size of 0 bytes, the other has umm...corrupted text, but then, I'm writing these as binary files so are they SUPPOSED to show up in notepad then?? Also, 1 other problem, I declared a variable as long, but this variable can't take values greater than 65000! I thought even unsigned ints could take more than that..I'm using Turbo c++ 3, is that like really outdated??

    So can someone tell me what I'm doing wrong in the create file function?

    What would you suggest I should use instead of gets? cin.getline? I need to take multiple words for the addresses so I can't use cin...

    Is there anything wrong in keeping main as void? I used int main a couple of times but I don't see any reason why I should use it over void main?

    Thanks for all the help!

    Code:
    //STRUCTURES FOR STAFF FILE AND STAFF SALARY FILE...........................................................................
    //Staff structure
    struct staff
    {
    int empno;
    char na[20];
    char add[20];
    long tp;
    int dj;
    int dd;
    char desig[20];
    char dept[20];
    long double bsal;
    }z;
    
    //Salary structure
    struct sal
    {
    int empno;
    long double bsal;
    long double da;
    long double hra;
    long double ca;
    long double medical;
    long double pf;
    long double itax;
    long double gsal;
    long double netsal;
    }y;
    
    
    //FUNCTIONS.................................................................................................................
    
    //MAIN FUNCTIONS(TO BE LOADED FROM MAIN FUNCTION)
    //Create file function to enter records for both salary and staff files
    void create()
    {
    clrscr();
    long count;//variable used to time delay loop
    cout<<"\nHow many records do you wish to create?\n";
    cin>>n;
    ofstream f1,f2;
    f1.open("staff.dat",ios:ut|ios::binary);
    f2.open("salary.dat",ios:ut|ios::binary);
    for(int i=0;i<n;i++)
    {
    cout<<"\nEnter employee number\n";
    cin>>z.empno;
    cout<<"Enter name of employee\n";
    gets(z.na);
    cout<<"Enter Phone number of employee\n";
    cin>>z.tp;
    cout<<"Enter address of employee\n";
    gets(z.add);
    cout<<"Enter date of joining of employee\n";
    cin>>z.dj;
    cout<<"Enter date of birth of employee\n";
    cin>>z.dd;
    cout<<"Enter designation of employee\n";
    gets(z.desig);
    cout<<"Enter department\n";
    gets(z.dept);
    cout<<"Enter basic salary\n";
    cin>>z.bsal;
    cout<<"\nWriting Staff file.....\n";
    f1.write((char*)&z,sizeof(z));
    cout<<"\nFile successfully created!\n";
    cout<<"\n\nEnter information for Staff Salary file\n";
    cout<<"Enter medical allowance\n";
    cin>>y.medical;
    y.empno=z.empno;
    y.bsal=z.bsal;
    y.hra=z.bsal*0.15;
    y.da=z.bsal*0.3;
    y.pf=z.bsal*0.08;
    y.ca=z.bsal*0.1;
    y.gsal=z.bsal+y.da+y.hra+y.ca;
    y.itax=y.gsal*0.3;
    y.netsal=y.gsal-(y.pf+y.itax);
    f2.write((char*)&y,sizeof(y));
    cout<<"\nWriting Staff salary file\n";
    cout<<"File successfully created!\n";
    }
    cout<<"Returning to Main menu.......\n";
    f1,f2.close();
    for(count=0;count<=90000;count++);
    main();
    }//create()

  5. #5
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    cout<<"\nEnter employee number\n";
    cin>>z.empno;
    cout << "z.empno = " << z.empno << endl;

    either use your debugger to be sure each member variable is being read into or add a line to display the variables value after it is read in (see example above) to be sure that all user input values are being accepted. I am concerned that by mixing C++ I/O routines (cin >>) with C I/O routines (gets()), that you may not be reading everything in that you think. It appears as though you may be trying to use gets() if the variable value may have space in it somewher, and cin >> if it's a single token input. In C++ to handle multiple token input (e.g., Jane Doe for a name or 555 N. Second St. for an address) you can use getline(). When mixing getline() with other C++ istream methods (eg >>) you should consider using a call to ignore() between the last >> and getline.

    cout<<"\nEnter employee number\n";
    cin>>z.empno;
    cout << "z.empno = " << z.empno << endl;

    cout << "\nEnter employee name : eg, Jane Doe" << endl;
    cin.ignore(size, term);
    cin.getline(z.empname, 35, '\n');
    cout << "z.empname = " << z.empname << endl;

    where size is the number of char you want to ignore, if there is that many in the input buffer after the call to >>, and term is the termination char, which can be any valid char. The prototype for ignore has default value of 1 for size, and newline char for term, if you don't specify them.


    Once you are convinced you've captured all the user input, then make sure your ofstreams are opened.

    ofstream f1,f2;
    f1.open("staff.dat",iosut|ios::binary);
    f2.open("salary.dat",iosut|ios::binary);
    if(f1.is_open())
    cout << "file opened successfully" << endl;
    //or alternate syntax
    if(!f2)
    cout <<"unable to open salary.dat file" << endl;

    If that still doesn't clear things up, then simplify your design by writing another program, such as this:
    Code:
    #include <fstream>
    struct A
    {
       int first;
    };
    struct B
    {
      char name[30];
    };
    int main()
    {
      //declare instances of each struct
      A a;
      B b;
      
      //initialize each object
      a.first = 3;
      strcpy(b.name, "Jane Doe");
    
      //declare an output stream
      ofstream fout;
    
      //associate stream with file, using binary format
      fout.open("sample.dat", ios::binary);
    
      //confirm file opened successfully
      if(!fout)
        cout << "unable to open sample file" << endl;
    
      //write to file 
      fout.write(reinterpret_cast<char*>(&a), sizeof(a));
      fout.write(reinterpret_cast<char*>(&b), sizeof(b));
      fout.close();
      
      //declare new variables
      A a1;
      B b1;
    
      //declare input stream, associate with file using binary format
      ifstream fin("sample.dat", ios::binary);
    
      //confirm file opened
      if(!fin)
        cout << "unable to open sample.dat" << endl;
    
      //read data into objects
      fin.read(reinterpret_cast<char*>(&a1), sizeof(a1));
      fin.read(reinterpret_cast<char*>(&b1), sizeof(b1));
    
      //confirm read was successful
      cout << "a1.first = " << a1.first << endl;
      cout << "b1.name = " << b1.name << endl;
    
      fin.close()
    }
    that covers everything you want to do, but without so much detail/fluff to get in the way of understanding the basic problem.

  6. #6
    Registered User kiss_psycho's Avatar
    Join Date
    Feb 2003
    Posts
    49
    this might sound strange and unconventional i guess, but could you try reading into seperate variables and then assigning the structure elements -- this is a strange problem with turbo C++. this occurs sometimes. i mean i got freaking crazy at a time when i could NOT read into a float element of a structure..
    Definition of Programmer : A red-eyed mumbling mammal capable of conversing with inanimate objects.

    Happy Hunting...
    The Root

  7. #7
    Registered User
    Join Date
    Oct 2003
    Posts
    5
    Ok, now I'm certain that the file is NOT being written into, any attempt to read this file and display just draws blanks...the file opens fine though(using !f.isopen() as elad said), so I have absolutely no idea why! Oh I tried changing gets to getline but my trubo c++ version is soo old that getline doesn't work on it, that is, it reads endline immediately, or more precisely my output will be like:-
    Enter employee number
    30
    Enter employee name
    Enter employee telephone number

    ie. It doesn't stop to receive input at this juncture, further, my school has the same thing and this project I'm supposed to submit will have to use the same trubo c++ version so I can't use getline at school either, are there any other suggestions as to why these files don't write?

    Thanks a bunch for the help so far!

    P.S.
    I tried ur idea kiss_psycho but didn't work either!!

  8. #8
    Registered User
    Join Date
    Oct 2003
    Posts
    5
    Some more info:-
    The Staff file I write has a file size of 0 bytes, while the salary file has 1 byte, so maybe its just the staff file thats not being written into...also, I used cin instead of gets and entered strings without spaces to check whether gets was the problem..still doesn't work!! I hate bug squashing!

  9. #9
    Registered User
    Join Date
    Oct 2003
    Posts
    5
    Ok, 1 last thing, the structure I am writing into doesn't seem to work even for simple files UNLESS I have only 1 record, that is, just one record is being written into the file, in all other cases it doesn't work..does anyone have any idea why? What is the exact procedure for writing mutliple structure records into a file(without using arrays of structures)...?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  2. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  3. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM