Solved

Read and write files

Posted on 2004-04-09
44
505 Views
Last Modified: 2008-02-01
I would like to read a text file which contains 1000 lines of data (mainly text data) and split the contents into 4 output text files, in which each file will contain 250 lines of data.
I've noticed the need to use _hread function (Turbo C++ function) but need some sample programs related to it.
Please throw some ideas on this matter. My environment is Borland Turbo C++.
0
Comment
Question by:showbix
  • 18
  • 13
  • 10
  • +1
44 Comments
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
There are two approaches

1) You know the no of characters appearing in each line & it remains constant across all the lines

In this, u can use fread () to read       250 * No. Of Characters in Each Line       and then use write () to write this data to other file

2) The no of characters in each line is different
You should read line by line using getline() and write then other files keeping a count of the no of lines read & changing the other output file after each 250 lines have been written

Amit
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
The following example reads the first line & writes it to other file

#include <iostream>
#include <fstream>

using namespace std ;

int main(int argc, char* argv[])
{
      ifstream ifile ( "c:\\input.txt" ) ;
      ofstream ofile ( "c:\\output.txt" ) ;
      string line ;
      getline ( ifile, line ) ;
      ofile << line ;
      
    system("pause");
      return 0;
}



Amit
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
Likewise, as shown above, u could build the logic for writing 250 lines and then changing the output file

Here is a reference to the I/O library

http://www.cplusplus.com/ref/iostream/

Amit
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
Try this:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void main()
{
  ifstream ifs("x1000.dat");
  ofstream ofs1("x1.dat");
  ofstream ofs2("x2.dat");
  ofstream ofs3("x3.dat");
  ofstream ofs4("x4.dat");
  ofstream* pofsArr[] = { &ofs1, &ofs2, &ofs3, &ofs4 };
  ofstream* pofs = &ofs1;

  int nLines = 0;
  int nFile  = 0;
  string line;
  while (!ifs.eof())
  {
      getline(ifs, line);
      *pofs << line << endl;
      if ((++nLines)%250==0)
      {
          pofs = pofsArr[++nFile];
      }
  }

  for (int i = 0; i < 4; i++)
  {
     pofsArr[i]->close();
  }
}

Regards, Alex
0
 

Author Comment

by:showbix
Comment Utility
Hi Sys_Prog.
Is your sample program work in Turbo C++?
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
Yep, it works

U probably have include this way

#include <iostream.h>
#include <fstream.h>

instead of

#include <iostream>
#include <fstream>

But the later one (as I shown in my example) is the new standard
Amit


0
 

Author Comment

by:showbix
Comment Utility
Hi Sys_Prog.
declaration sysntax error at this line -->>using namespace std ;
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
Do not use
using namespace std ;


Just comment it
Amit
0
 

Author Comment

by:showbix
Comment Utility
Hi Sys_Prog.
Can you explain me line by line your program code as I need to understand it.
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
The Turbo C++ compiler must be comliang to the old C++ standard,

Amit
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
Try this, that is 'old' C++ not using C++ Standard

#include <stdio.h>
#include <fstream.h>
#include <iostream.h>

void ff()
{
  ifstream ifs("x1000.dat");
  ofstream ofs1("x1.dat");
  ofstream ofs2("x2.dat");
  ofstream ofs3("x3.dat");
  ofstream ofs4("x4.dat");
  ofstream* pofsArr[] = { &ofs1, &ofs2, &ofs3, &ofs4 };
  ofstream* pofs = &ofs1;

  int nLines = 0;
  int nFile  = 0;
  char line[1024];
  while (!ifs.eof())
  {
      ifs.getline(line, sizeof(char));
      *pofs << line << endl;
      if ((++nLines)%250==0)
      {
          pofs = pofsArr[++nFile];
      }
  }

  for (int i = 0; i < 4; i++)
  {
     pofsArr[i]->close();
  }
}

Regards, Alex
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
int main(int argc, char* argv[])
{
     ifstream ifile ( "c:\\input.txt" ) ;              // declare an input stream type of object which is used to read a file, It also        opens the file "c:\\input.txt"
     ofstream ofile ( "c:\\output.txt" ) ;           // declare an output stream type of object which is used to write to a file, It also opens the file "c:\\output.txt" for writing
     string line ;                                            // Declare a string type of object to read a line
     getline ( ifile, line ) ;                               // Read a line from the input file and store it in the line variable
     ofile << line ;                                         // Write the read line into the output file
     return 0;
}

Amit
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
Sorry a typo, it should be

    sizeof(line)

and not

    sizeof(char)

Regards, Alex
0
 

Author Comment

by:showbix
Comment Utility
Hi itsmeandnobodyelse.
Linker Warning.
No module definition file specified.

Linker Error.
Un defined symbol _main in library file C:\TCWIN45\LIB\cwl.lib in module winmain.

Could you explain me what's the error all about.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
I made function ff() and not main() as i compiled it  using an existing project

Simply change

   void ff()

to

   int main(int argc, char* argv[])

and add

   return 0;

to the end of the function.

Regards, Alex

 



0
 

Author Comment

by:showbix
Comment Utility
Hi itsmeandnobodyelse.
I have changed your code from
--->> void ff()
to
-->> int main(int argc, char* argv[])
and it works fine.
0
 

Author Comment

by:showbix
Comment Utility
Hi

The content of my source file is like this
COMMAND=print  
LENGTH=63    
LENGTH_COL=32    
CUTFORM=nd70  
CUTFORM_DTL=rec  
DATA=I'm learning C++
COMMAND=print  
LENGTH=63    
LENGTH_COL=32    
CUTFORM=nd70  
CUTFORM_DTL=rec  
DATA=I'm also learning Java
COMMAND=print  
LENGTH=63    
LENGTH_COL=32    
CUTFORM=nd70  
CUTFORM_DTL=rec  
DATA=Now I'm trying to learn Turbo C++

and so on....
How do I check for
COMMAND, LENGTH, LENGTH_COL, CUTFORM, CUTFORM_DTL, DATA in every line, get the value of them and write to output files?






0
 

Author Comment

by:showbix
Comment Utility
COMMAND, LENGTH, LENGTH_COL, CUTFORM, CUTFORM_DTL, DATA
is considered as one block of data. How do I read a block and write to a file, read next block and write to a new next file and so on.
0
 

Author Comment

by:showbix
Comment Utility
I have increased the points as you guys really helpful in this problems.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility

     ...
     ifs.getline(line, sizeof(line));

     // find "=" , e. g. in "COMMAND=print"
     char* p = strchr(line, '=');
     if (p != NULL)  
         // p points now to "=print"
         *pofs << ++p << endl;       // skip '='
     else
         *pofs << line << endl;      
     ...

Regards, Alex
0
 

Author Comment

by:showbix
Comment Utility
Hi itsmeandnobodyelse.
As per your code, the output are defined early in the process, that is
  ofstream ofs1("x1.dat");
  ofstream ofs2("x2.dat");
  ofstream ofs3("x3.dat");
  ofstream ofs4("x4.dat");

Is there any possibility to dynamically create the output file based on the total numbers of "data block".
-----------------------------------------------------------------------------
my previous question...
COMMAND, LENGTH, LENGTH_COL, CUTFORM, CUTFORM_DTL, DATA
is considered as one block of data. How do I read a block and write to a file, read next block and write to a new next file and so on.
------------------------------------------------------------------------------
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
Look at this,

#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <iostream.h>
#include <string.h>

#define MAX_OPT  100
#define MAX_CMD  100
#define MAX_KEY  100
#define MAX_VAL  100

struct CommandOption
{
    char  pszKey[MAX_KEY];
    char  pszVal[MAX_VAL];
};

struct CommandData
{
    CommandOption* optArr[MAX_OPT];
    int            nOpts;
    CommandData() :  nOpts(0) { memcpy(optArr, 0, MAX_OPT*sizeof(CommandOption)); }
};

int main(int argc, char* argv[])
{
  ifstream ifs("x1000.dat");

  int nLines = 0;
  int nFile  = 0;
  char line[1024];
  char file[32] = "x";
  ofstream* pofs = NULL;

  CommandData* cmdArr[MAX_CMD];
  CommandData* pCmd = NULL;


  while (!ifs.eof())
  {
      ifs.getline(line, sizeof(char));
      if (strstr(line, "COMMAND=") == line)
      {
          if (pofs != NULL)
              pofs->close();

          itoa(nFile, &file[strlen(file)], 10);
          pofs = new ofstream(file);

          pCmd = cmdArr[nFile] = new CommandData;
      }
      if (pCmd != NULL)
      {
          // write full line to output file
          *pofs << line << endl;

          // find '='
          char* p = strchr(line, '=');
          if (p != NULL)  
          {
              *p = '\0';   // change '=' to terminating zero
              CommandOption* pOpt = new CommandOption;
              strcpy(pOpt->pszKey, line);
              strcpy(pOpt->pszVal, ++p);
              int n = pCmd->nOpts++;
              pCmd->optArr[n] = pOpt;

          }
      }
  }
  if (pofs != NULL)
      pofs->close();

  return 0;
}

That dynamically creates output files and all keys and values are stored to struct CommandOption. All options til next command get stored to struct CommandData and main holds an array of these. Maybe you have to increase MAX_.... constants or try to make it fully dynamically. You also have to add some checks on wrong input.

Regards, Alex

0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
There is a missing

   ++nFile;

below

     pCmd = cmdArr[nFile] = new CommandData;


Regards, Alex

0
 

Author Comment

by:showbix
Comment Utility
Hi itsmeandnobodyelse
1. The program hang.
2. What are name extension of the output files?

My sample data
COMMAND=display  
LENGTH=40    
LENGTH_COL=0    
CUTFORM=  
CUTFORM_DTL=  
DATA=   The testing data
COMMAND=display  
LENGTH=40    
LENGTH_COL=0    
CUTFORM=  
CUTFORM_DTL=  
DATA=   Payment   5.00    
COMMAND=display  
LENGTH=40    
LENGTH_COL=0    
CUTFORM=  
CUTFORM_DTL=  
DATA=   Payment   45.00    
COMMAND=display  
LENGTH=40    
LENGTH_COL=0    
CUTFORM=  
CUTFORM_DTL=  
DATA=Balance                        5.00    
COMMAND=printlogo  
LENGTH=25    
LENGTH_COL=140  
CUTFORM=nd70  
CUTFORM_DTL=rec  
DATA=                        
0
 

Author Comment

by:showbix
Comment Utility
I have already put the "++nFile;" syntax in the code below.
-------------------------------------------------------------------------
      if (strstr(line, "COMMAND=") == line)
      {
          if (pofs != NULL)
              pofs->close();

          itoa(nFile, &file[strlen(file)], 10);
          pofs = new ofstream(file);

                   pCmd = cmdArr[nFile] = new CommandData;
          ++nFile;
      }
-------------------------------------------------------------------------
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 50 total points
Comment Utility
Removed some bugs:

#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <iostream.h>
#include <string.h>

#define MAX_OPT  100
#define MAX_CMD  100
#define MAX_KEY  100
#define MAX_VAL  100

struct CommandOption
{
    char  pszKey[MAX_KEY];
    char  pszVal[MAX_VAL];
};

struct CommandData
{
    CommandOption* optArr[MAX_OPT];
    int            nOpts;
    CommandData() :  nOpts(0) { memset(optArr, 0, MAX_OPT*sizeof(CommandOption*));
    }
};

int main(int argc, char* argv[])
{
    ifstream ifs("x1000.txt", ios::in | ios::nocreate );
  if (ifs.fail())
  {
      cout << "open failed" << endl;
      return 1;
  }

  int nLines = 0;
  int nFile  = 0;
  char line[1024];
  char file[32] = "x";
  ofstream* pofs = NULL;

  CommandData* cmdArr[MAX_CMD] = { NULL };
  CommandData* pCmd = NULL;


  while (!ifs.eof())
  {
      ifs.getline(line, sizeof(line));
      if (strstr(line, "COMMAND=") == line)
      {
          if (pofs != NULL)
              pofs->close();

          itoa(nFile, &file[1], 10);
          strcpy(&file[strlen(file)], ".txt");
          pofs = new ofstream(file);

          pCmd = new CommandData;    
          cmdArr[nFile++] = pCmd;
      }
      if (pCmd != NULL)
      {
          // write full line to output file
          *pofs << line << endl;

          // find '='
          char* p = strchr(line, '=');
          if (p != NULL)  
          {
              *p = '\0';   // change '=' to terminating zero
              CommandOption* pOpt = new CommandOption;
              strcpy(pOpt->pszKey, line);
              strcpy(pOpt->pszVal, ++p);
              int n = pCmd->nOpts++;
              pCmd->optArr[n] = pOpt;

          }
      }
  }
  if (pofs != NULL)
      pofs->close();

  for (int i = 0; i < nFile; i++)
  {
      cout << "-------------------------  file x" << i << ".txt ----------------------" << endl;
      for (int n = 0; n < cmdArr[i]->nOpts; n++)
      {
          cout << cmdArr[i]->optArr[n]->pszKey << "=" << cmdArr[i]->optArr[n]->pszVal << endl;
      }
  }
  cout << "------------------------------------------------ ----------------------" << endl;
  cout << "Total: " << nFile << " files" << endl << endl;
  return 0;
}

Regards, Alex
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
showbix,
There are free compilers available that are much more compliant to the correct C++ standard.
The GNU compiler is free, and would probably better for your requirements then Turbo C++.

I recommend you upgrade to something better.

See following links for free compilers and IDE's.


Bloodshed Dev-C++ Compiler is available at
http://www.bloodshed.nu/devc.html

http://visual-mingw.sourceforge.net/ (IDE ONLY)  use with MinGW compiler

http://www.mingw.org/index.shtml (MinGW compiler only)

http://www.delorie.com/ (DJGPP compiler only)

http://www.digitalmars.com/ (Digital Mars compiler only)

http://www.openwatcom.org/ (Watcom  compiler and IDE)

http://www.gnu.org/software/gcc/gcc.html (GCC compiler)

http://www.cygwin.com
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
Correction:
>>There are free compilers available that are much more compliant to the *current* C++ standard.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
If you change to any of the Compilers Axter has recommended (i would buy  VC6.0 from ebay for little money) that supports C++ standard - and i recommend it also -, you had to do this:

#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

#define MAX_OPT  100
#define MAX_CMD  100

struct CommandOption
{
    string strkey;
    string strVal;
};

struct CommandData
{
    CommandOption* optArr[MAX_OPT];
    int            nOpts;
    CommandData() :  nOpts(0) { memset(optArr, 0, MAX_OPT*sizeof(CommandOption*));
    }
};

int main(int argc, char* argv[])
{
    ifstream ifs("x1000.txt");
  if (ifs.fail())
  {
      cout << "open failed" << endl;
      return 1;
  }

  int nLines = 0;
  int nFile  = 0;
  string line;
  string file = "x";
  ofstream* pofs = NULL;

  CommandData* cmdArr[MAX_CMD] = { NULL };
  CommandData* pCmd = NULL;

  int pos = 0;

  while (!ifs.eof())
  {
      getline(ifs, line);
      if ((pos = line.find("COMMAND=")) != string::npos )
      {
          if (pofs != NULL)
              pofs->close();
          char fnum[11];
          itoa(nFile, fnum, 10);
          file += fnum;
          file += ".txt";
          pofs = new ofstream(file);

          pCmd = new CommandData;    
          cmdArr[nFile++] = pCmd;
      }
      if (pCmd != NULL)
      {
          // write full line to output file
          *pofs << line << endl;

          // find '='
          pos = line.find('=');
          if (pos  != string::npos)  
          {
              CommandOption* pOpt = new CommandOption;
              pOpt->strKey = line.substr(0, pos);
              pOpt->strVal  = line.substr(pos+1);
              int n = pCmd->nOpts++;
              pCmd->optArr[n] = pOpt;

          }
      }
  }
  if (pofs != NULL)
      pofs->close();

  for (int i = 0; i < nFile; i++)
  {
      cout << "-------------------------  file x" << i << ".txt ----------------------" << endl;
      for (int n = 0; n < cmdArr[i]->nOpts; n++)
      {
          cout << cmdArr[i]->optArr[n]->strKey << "=" << cmdArr[i]->optArr[n]->strVal << endl;
      }
  }
  cout << "------------------------------------------------ ----------------------" << endl;
  cout << "Total: " << nFile << " files" << endl << endl;
  return 0;
}

Regards, Alex


0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
Try this code,
this would work for any number of sections

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std ;

int main(int argc, char* argv[])
{
      ifstream ifile ( "c:\\input.txt" ) ;
      fstream ofile ;
      
      int outFileCount = 0 ;
      string      outFileName ;
      string line ;
      
       ofile.open ( "c:\\outputFile1.txt", ofstream::out ) ;                  
      
      while ( getline ( ifile, line ) ) {
            if ( line.find ( "COMMAND=", 0 ) != string::npos )  {
                  outFileCount++ ;
                  ofile.close () ;
                  ostringstream s ;
                     s << outFileCount ;
                  outFileName = "c:\\outputFile" + s.str() + ".txt" ;
                  ofile.open ( outFileName.c_str(), ofstream::out ) ;            
            }
            ofile << line << endl ;
       }
      ofile.close () ;      
    system("pause");
      return 0;
}


Amit
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
Basically the logic goes this way

Read a Line from Input File
Check if it is containing "COMMAND=" string indicating that it is to be written in a new file
IF the line contains "COMMAND=", Close the output file already opened, Open a new file with a name generated as c:\outputFile1.txt OR c:\outputFile2.txt OR c:\outputFile3.txt........so on

Write the line to the file
Continue from first step


Amit
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
Bloodshed Dev-C++ Compiler is available at
http://www.bloodshed.nu/devc.html

is much much better (complaint) than VC++ 6.0

and its free

Amit
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>is much much better (complaint) than VC++ 6.0

My 2 Cents:
The GNU 3.x compiler is much better for C/C++ compliance then VC++ 6.0.
However, the available free IDE's are not as good as VC++ 6.0.

VC++ 6.0 has the best IDE out of all the compilers/IDE's I've used in the past.  (IMHO even better then VC++ 7.x)

So even though it has a poor rating for C/C++ compliance, I would still recommend it over the GNU compiler.

However, if you don't have the money to spend, then of course the GNU compiler is the best choice IMHO.
0
 

Author Comment

by:showbix
Comment Utility
Hey guys,

I have tried execute code above but sometimes it throws "general protection error" and I suspect this is due to the file size and limitation of the functions being used.

I have read something about IO operation in Turbo C++ which mentioned that _hread and GlobalAlloc is good for reading file larger than 64K in size. Have any ideas of it?
0
 

Author Comment

by:showbix
Comment Utility
Hi itsmeandnobodyelse.
I have tested your code with 2K size of source file and it works fine but when I tried with 48K size file, it throws "General Protection Error". What's that error means?
FYI, Several output files are generated in the directory.
0
 
LVL 10

Assisted Solution

by:Sys_Prog
Sys_Prog earned 150 total points
Comment Utility
This code perfectly worlks for > 64kb file in TC++
But I highly recommend u to get a standrad C++ compiler and use my previous code....That is much more simpler although the logic I have used is same

#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
     ifstream ifile ( "c:\\input.txt" ) ;
     ofstream ofile ;
     
     int outFileCount = 0 ;
     char line[100] ;
     
      ofile.open ( "c:\\new\\out1.txt", ofstream::out ) ;
     
     while ( !ifile.eof() ) {
        ifile.getline ( line, 100 ) ;
        if ( strstr ( line, "COMMAND" ) != NULL ) {
             outFileCount++ ;
               ofile.close () ;
               
               // Generate the new file name
             char outFileName [30] = { '\0' } ;
             strcat ( outFileName, "c:\\new\\out" ) ;
             char temp [10] = { '\0' } ;
             itoa ( outFileCount, temp, 10 ) ;
             strcat ( outFileName, temp ) ;
             strcat ( outFileName, ".txt" ) ;

             ofile.open ( outFileName, ofstream::out ) ;
        }
        ofile << line ;
      }
     ofile.close () ;
     cout << "done" ;
    return 0;
}

Amit
0
 

Author Comment

by:showbix
Comment Utility
Hi Amit.
Your program hang when it executed.
This is the file that I have modified i.e input and output path.
----------------------------------------------------------------------------
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
        ifstream ifile ( "c:\tmp3\inputf.txt" ) ;
     ofstream ofile ;
     
     int outFileCount = 0 ;
     char line[100] ;
     
            ofile.open ( "c:\tmp3\out1.txt", ofstream::out ) ;
     
     while ( !ifile.eof() ) {
       ifile.getline ( line, 100 ) ;
       if ( strstr ( line, "COMMAND" ) != NULL ) {
            outFileCount++ ;
               ofile.close () ;
               
               // Generate the new file name
            char outFileName [30] = { '\0' } ;
            strcat ( outFileName, "c:\tmp3\out" ) ;
            char temp [10] = { '\0' } ;
            itoa ( outFileCount, temp, 10 ) ;
            strcat ( outFileName, temp ) ;
            strcat ( outFileName, ".txt" ) ;

            ofile.open ( outFileName, ofstream::out ) ;
       }
       ofile << line ;
      }
     ofile.close () ;
     cout << "done" ;
    return 0;
}
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
"c:\tmp3\out"

should be

"c:\\tmp3\\out"

Likewise, at other places also, wherever u use one backslash for a filepath, u should specify two

Amit
0
 

Author Comment

by:showbix
Comment Utility
Hi amit.
The output format is wrong.
COMMAND=print  LENGTH=63    LENGTH_COL=32    CUTFORM=nd70  CUTFORM_DTL=rec  DATA=================================                      
It should be like this.
COMMAND=print
 LENGTH=63    
LENGTH_COL=32    
CUTFORM=nd70  
CUTFORM_DTL=rec  DATA=================================                      
0
 

Author Comment

by:showbix
Comment Utility
0
 
LVL 10

Expert Comment

by:Sys_Prog
Comment Utility
showbix,

I get the output as u expect
Ayway, if u do not, then just replace the line
 ofile << line ;
with
 ofile << line << endl ;
in my code

Amit
0
 

Author Comment

by:showbix
Comment Utility
Thanks amit.
Great solution from you. Hope you can look into my other Question at
http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20949578.html
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
I changed the program by removing any limitations.

I don't know whether you'll need it after all.

Regards, Alex

#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <iostream.h>
#include <string.h>

struct CommandOption
{
    char*  pszKey;
    char*  pszVal;
    CommandOption() : pszKey(NULL), pszVal(NULL) {}
    CommandOption( const char* pszK, const char* pszV)  
    {
        pszKey = new char[strlen(pszK)+1]; strcpy(pszKey, pszK);
        pszVal = new char[strlen(pszV)+1]; strcpy(pszVal, pszV);
    }
    ~CommandOption() { delete [] pszKey; delete [] pszVal; }
};

struct CommandData
{
    CommandOption** pOptArr;
    int             nOpts;
    CommandData() : nOpts(0), pOptArr(NULL) {}
    ~CommandData()
    {
        for (int i = 0; i < nOpts; i++)
            delete pOptArr[i];
        delete [] pOptArr;
    }
    void AddOpt(const char* pszK, const char* pszV)
    {
        CommandOption** pOpts = new CommandOption*[nOpts+1];
        if (nOpts > 0)
        {
            memcpy(pOpts, pOptArr, sizeof(CommandOption*)*nOpts);
            delete []pOptArr;
        }
        pOpts[nOpts++] = new CommandOption(pszK, pszV);
        pOptArr        = pOpts;
    }
};

int main(int argc, char* argv[])
{
    ifstream ifs("xall.txt", ios::in | ios::nocreate );
    if (ifs.fail())
    {
        cout << "open failed" << endl;
        return 1;
    }
   
    int nLines = 0;
    int nFile  = 0;
    char line[1024];
    char file[32] = "x";
    ofstream* pofs = NULL;
   
    CommandData** pCmdArr = NULL;
    CommandData** pCmds   = NULL;
    CommandData*  pCmd    = NULL;
   
   
    while (!ifs.eof())
    {
        ifs.getline(line, sizeof(line));
        if (strstr(line, "COMMAND=") == line)
        {
            if (pofs != NULL)
                pofs->close();
           
            itoa(nFile, &file[1], 10);
            strcpy(&file[strlen(file)], ".txt");
            pofs = new ofstream(file);
           
            pCmd  = new CommandData;
            pCmds = new CommandData*[nFile+1];
            if (pCmdArr != NULL)
            {
                memcpy(pCmds, pCmdArr, sizeof(CommandData*)*nFile);
                delete [] pCmdArr;
            }
            pCmds[nFile++] = pCmd;
            pCmdArr = pCmds;
        }
        if (pCmd != NULL)
        {
            // write full line to output file
            *pofs << line << endl;
           
            // find '='
            char* p = strchr(line, '=');
            if (p != NULL)  
            {
                *p = '\0';   // change '=' to terminating zero
                pCmd->AddOpt(line, ++p);  
            }
        }
    }
    if (pofs != NULL)
        pofs->close();
   
    for (int i = 0; i < nFile; i++)
    {
        cout << "-------------------------  file x" << i << ".txt ----------------------" << endl;
        for (int n = 0; n < pCmdArr[i]->nOpts; n++)
        {
            cout << pCmdArr[i]->pOptArr[n]->pszKey << "=" << pCmdArr[i]->pOptArr[n]->pszVal << endl;
        }
    }
    cout << "------------------------------------------------ ----------------------" << endl;
    cout << "Total: " << nFile << " files" << endl << endl;

    delete [] pCmdArr;
    return 0;
}
0
 

Author Comment

by:showbix
Comment Utility
Thanks  itsmeandnobodyelse.
I still need your code eventhough Sys_Prog already done the solution earlier. BTW, thanks to you guys for helping me out.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now