• Welcome to Jose's Read Only Forum 2023.
 

ProgEx20 - Simple I/O Example Of Array of Structs To Text File

Started by Frederick J. Harris, November 07, 2009, 09:13:44 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frederick J. Harris


/*
  ProgEx20   -- This is a C++ program and must be set up as such!  Save this
                file as Main.cpp.
               
  Well, now I've done it!  I've dug myself into a hole and now I can't get out!
  And how I thought things were going so well with this tutorial!  We've covered
  basic output using printf(), pointer (byval) and reference parameter passing
  mechanisms both in C and C++,  implicit and explicit dynamic linking using
  both C/C++ and PowerBASIC servers and clients, and now finally structs and how
  using them differs in C and C++.  I decided that in this tutorial, along with
  further use of structs (UDTs), I'd introduce file access in C/C++.  I created
  anew our Employee struct we've been using for the last two tutorials below,
  and decided to show how to write this data in the form of arrays of these
  structs to a comma delimited text file.  Sounds good huh?  Well, the problem
  is, if I'm going to show how to write them to a comma delimited text file, I
  ought to for the sake of symetry show how to read the data back out of the
  text files and reconstitute it in the same form in the Employee structs where
  it originally existed.  The reading it back out part isn't hard.  The hard
  part is reconstituting it back to its original form.  For you see, C and C++
  just don't have the high level built in file handling capacities that Power-
  BASIC has.  You'll see why momentarily.  So I've resigned myself for what I
  have to cover.  Maybe things will work out afterall.  So in this tutorial I'll
  show as much as I can about file access, and continue with the discussion of
  structs from the last two tutorials.  The next couple tutorials are going to
  have to be about what I've neglected up until now in C++, and that's classes.
  For you see, we have been accumulating problems, and they are piling up. 
 
  First, we had the problem of not being able in C or C++ to simply assign a
  string to any kind of variable like we would do in PowerBASIC.  We've had to
  first allocate memory in some kind of buffer, then use strcpy() to copy the
  bytes into the buffer.  If you've been feeling this is pretty ridiculous
  you're in good company!
 
  Now we've run into the problem (or more accurately, I've run into the problem)
  of there being no easy way to get some data back out of a file to which it was
  written.  The answer to all these problems and many more can be found in
  C++ classes.  So that's what the next few tutorials will be about.  But for
  now, lets see how far we can get with my original plan.  When we can't go any
  farther we'll stop, study classes, then pick up where we left off here.
 
  So, in the program below you'll see at top our Employee struct and you'll also
  see I didn't use a typedef with it.  In C++ you don't need the typedef
  statement to be able to create an instance of the UDT like so...
 
  Employee emp;
 
  That's one of the changes made in the C++ language from C.  Also in the
  program below note I created an array of Employee structs like so...
 
  Employee emp[2];
 
  Array subscripting in C/C++ does not work like in PowerBASIC where the number
  in brackets represents the upper bound of the array.  In C/C++ the number in
  brackets represents the count of elements.  What this means is that the above
  declaration will create an emp[0] and an emp[1].  There won't be any emp[2].
  If you need an emp[2] then your declaration would need to be for three
  elements like so...
 
  Employee emp[3];
 
  Differnt from PowerBASIC but logical, not?  So down in main() you can see how
  I filled both elements with some character string and numeric data.
 
  So now we've got data for two folks in our Employee array of structs, so lets
  write the data to a comma delimited text file.  There is a struct defined in
  stdio.h named FILE.  Feel free to open stdio.h in a text editor and examine it
  if you like, but don't get concerned if you don't understand it very well.
  Using it is fairly easy.  To read/write text files using the C runtime library
  (the best way to do it in my opinion) you simply need to declare a pointer to
  this FILE struct like so...
 
  FILE* fp;
 
  Its actually a better idea to do it like this...
 
  FILE* fp=NULL;
 
  The reason I say this is that we are going to call a function named fopen() to
  open a file very much like BASIC's 'Open' statement, and if the function fails
  we can test for a NULL.  If the function succeeds we'll have a valid file
  pointer in fp.  The statement to open a file named "Data.dat" in the current
  directory for writting only (OUTPUT in basic speak) is...
 
  fp=fopen("Data.dat","w");
 
  The "w" stands for 'writing'.  For read operations you use "r".  Fairly basic
  really, even though it isn't BASIC!  By the way, this only applies to text
  files.  Binary files, which I havn't gotten to yet, require a "b".
                     
*/

#include <stdio.h>
#include <string.h>

struct Employee          //Same as Type Employee
{
char szName[32];   
char szAddress[32];
char szCity[16];
char szState[16];
char szCountry[16];
char szZipCode[16];
unsigned int iAge;
unsigned int iEmpNum;
double dblSalary;   
};                       //End Type

void Initialize(Employee* pEmp)
{
strcpy(pEmp[0].szName,"Martin Veneski");             //1st employee
strcpy(pEmp[0].szAddress,"1016 Wabash Street");
strcpy(pEmp[0].szCity,"Shamokin");
strcpy(pEmp[0].szState,"PA");
strcpy(pEmp[0].szCountry,"USA");
strcpy(pEmp[0].szZipCode,"17872");
pEmp[0].iAge=23;
pEmp[0].iEmpNum=123456;
pEmp[0].dblSalary=45000;

strcpy(pEmp[1].szName,"Raymond Latchkoski");         //2nd employee
strcpy(pEmp[1].szAddress,"1624 Tioga Street");
strcpy(pEmp[1].szCity,"Shamokin");
strcpy(pEmp[1].szState,"PA");
strcpy(pEmp[1].szCountry,"USA");
strcpy(pEmp[1].szZipCode,"17872");
pEmp[1].iAge=25;
pEmp[1].iEmpNum=789123;
pEmp[1].dblSalary=50000;
}

int main()
{
char szBuffer[256];
Employee emp[2];
FILE* fp;

Initialize(emp);
fp=fopen("Data.dat","w");  //Same as Open "Data.dat" For Output As #fp
for(unsigned int i=0; i<sizeof(emp)/sizeof(emp[0]); i++)  //For i=0 To 1
{
     fprintf                      //Print #fp, ...
     (
      fp,
      "%s,%s,%s,%s,%s,%s,%u,%u,%6.2f\n",
      emp[i].szName,emp[i].szAddress,emp[i].szCity,emp[i].szState,
      emp[i].szCountry,emp[i].szZipCode,emp[i].iAge,emp[i].iEmpNum,
      emp[i].dblSalary
     );
}     
fclose(fp);

fp=fopen("Data.dat","r");        //Same as Open "Data.dat" For Input As #fp
for(unsigned int i=0; i<2; i++)  //Same as For i=0 To 1
{
     fgets(szBuffer,256,fp);      //Same As Line Input #fp, szBuffer
     printf("%s",szBuffer);       //Same as Print szBuffer
}
fclose(fp);                      //Same as Close #fp
getchar();

return 0;
}

/*  --Output--
=============================================================================
Martin Veneski,1016 Wabash Street,Shamokin,PA,USA,17872,23,123456,45000.00
Raymond Latchkoski,1624 Tioga Street,Shamokin,PA,USA,17872,25,789123,50000.00
*/