Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

copy file and effect on dbf file 1

Status
Not open for further replies.

hugh7

Technical User
Mar 2, 2003
24
0
0
US
Hi There ,

I used the following code which I found on the net to copy files. I tried on a dbf file and it copies the file but it puts the first byte of the next record into the last field of the previous record. A dbf record begins with a delete byte that is either Ox20 for not deleted and 0x2A for deleted.
I tested the code with a deleted record and the * appeared in the last field of the previous record and the first field of the deleted record. All the field in each record begin with a space which I take to be the delete byte.
The file size after copying is exactly the same size as the orginal.

I don't understand how to fix this.

Here is the code I used:

#include <fstream>
#include <iostream>


int main(int argc, char **argv) {


if (argc < 3) {
std::cerr << &quot;usage: &quot; << argv[0] << &quot; [source] [destination]&quot; << std::endl;
return 1;
}


std::ifstream fin(argv[1]);
std::eek:fstream fout(argv[2], std::ios_base::eek:ut | std::ios_base::trunc);
if (fin.is_open() && fout.is_open())
fout << fin.rdbuf();// here's the line
fin.close();
fout.close();

return 0;
}

I tried various other copying file code and they all did the same thing.

Surely there is a way .

Any ideas appreciated.

Thanks
Hugh
 
Try the followings:
Code:
#include <iostream.h>
void copy(ofstream& dst, ifstream src)
{
	char c;
	while (dst && src.get(c))
		dst.put(c);
}
void main (void)
{

ifstream src;
ofstream dst;
src.open(&quot;C:\\src.dbf&quot;,ios::in);
if (!src)
{
	cout<<&quot;Error open input file src.dbf;&quot;<<endl;
	exit(1);
}
dst2.open(&quot;C:\\dst.dbf&quot;);
if (!dst)
{
cout<< &quot;Error open output dst.dbf&quot;<<endl;
}
copy(dst2,src);
src.close();
dst.close();
}

-obislavu-
 
By default i/o streams opened in text mode. It's wrong to copy binary files (dbfs are binary!) in text mode. Use ios_base::binary flag or (I think, better;) use <cstdio> file i/o with explicit buffering (via setbuf). Old good C files are part of C++ Standard.
In Windows env the best way to copy file: CopyFile() system function from <windows.h>:
Code:
if (!CopyFile(filename1,filename2,TRUE/*safe mode*/))
  cerr << &quot;Can't copy file.&quot; << endl;
 
Hi obislavu


I will try your sample.

Thanks for the tip.

Hugh
 
Hi ArkM

I will try what you suggest. I not sure how to code what you suggest re ios::binary or the setbuf.

I had looked at Microsoft for a copyfile function but couldn't find it . Thanks for that sample I will try it.

I also compared the copied file ( made by using the code in my original post) to the original dbf and found that the basic problem happened in the header part of the file.

At byte postion 176 the copied file had a 0x0D the correct value at this position is 0x0A. However this value was put in the next position (177). Then at position 193 the copied file had 0x0D . This should be at postion 192.
Finally the copied file had added a null at position 456 . This is where the correct data file starts.

I then fixed position 176, 177 and 192 and 193 and the odd data in the fields disappeared. I have not yet removed the added null at position 456. This added null explains the field data being pushed one character to the right i.e each field beginning with a space if not deleted or the asterisk if deleted.

Thanks again

Hugh
 
Hi hugh7
It's exactly a text mode stream effect. The output stream contains Windows line separator CR LF instead of original (binary) 0x0D. There are no any 'lines' in DBF file, but you forget to say about this fact (i.e. set ios_base::binary flag).
Code sceleton for CopyFile() using:
Code:
#include <windows.h>
#include <iostream>
int main(int argc, char* argv[])
{
  if (argc != 3)
  {
     cerr << &quot;Use: ....&quot; << endl;
     return 1;
  }
  if (!CopyFile(argv[1],argv[2],TRUE))
  {
    cerr << &quot;Can\'t copy file &quot; << argv[1] << endl;
    return 2;
  }
  ...
  return 0;
}
3rd param: TRUE => don't overwrite existent file;
FALSE => may overwrite.
Returns 0 if failed. Add more checking code as you wish.
C-style i/o sample:
Code:
#define BSZ (31*1024)
bool MyCopyFile(const char* from, const char* to)
{
  FILE* fin;
  FILE* fout;
  fin  = fopen(from,&quot;rb&quot;);
  fout = fopen(to,&quot;wb&quot;);
  if (!fin || !fout)
  {
     if (fin) fclose(fin);
     if (fout) fclose(fout);
     return false;
  }

  setvbuf(fin,0,_IOFBF,BSZ); // set file buffer
  setvbuf(fout,0,_IOFBF,BSZ);
  size_t rsz = 0;
  void* buff = malloc(BSZ); // or new char[BSZ]
  while ((rsz=fread(buff,sizeof(char),BSZ,fin)) != 0
	  && fwrite(buff,sizeof(char),BSZ,fout) == rsz)
	  ;
  bool res = (feof(fin) != 0); // returns 0 if eof or error
  free(buff); // or delete [] buff if allocated by new
  fclose(fin);
  fclose(fout);
  return res;
}
Well, you may use C++ streams, but I think, C-style code is faster. C++ streams was developed for text/format i/o (see B.Stroustrup's book about C++ design). In Windows use CopyFile (it copy file attrs too). But MyCopyFile will work on any systems (I hope;)...
Good luck!
 
hi ArkM,

Thanks again for the examples. I will try them both. I certainly need to learn more.
Since my last post I tested a few other examples and they all messed up at exactly the same spots in the header part of the file.
Do you recommend B. Stroustrup's book for learning C++? What about a book for C?

Hugh
 
Hi hugh7.
The best book about C++ (I'm sure) is &quot;The C++ Programming Language&quot; by B.Stroustrup. Read it for constant reference.
The second excellent book is Grady Booch's &quot;Object-oriented design ... in C++&quot; (sorry, I haven't it at hand now). Evidently, there are many others good books about C++. Alas, there are (much more) very bad books...
I think, the best book about C is K&R &quot;The C Programming Language&quot; (last edition).
Of course, C++ and C ISO/ANSI Standards are very useful sources too.
Make inet search to obtain further information.
P.S. Test my C-style sample carefully (it was improvized;).
Excelsior!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top