|
-
January 21st, 2004, 12:31 AM
#1
How to format my output using ofstream
Hi, I have a quick question on formatting.
I am writing a program that takes a buffer of type char* and writes it to a logfile via
logfile << (unsigned int*)bufffer1[i];
Unfortunately, the output is always in the format
0x000000E00x0000001F0x0000001E0x00000081
I would like to put it into the format
E0 1F 1E 81
but I can't figure out how to do it with ofstream. The code is below and kind of quick and dirty. I have thousands of these strings to look at, so if anyone has any idea I'd greatly appreciate it. Thanks for your time.
~Steve
// Compares a nonfunctional mpeg and the same file made functional
#include <fstream.h>
#include <iomanip>
const char * file1 = "test.mpeg";
const char * file2 = "testcorrected.mpeg";
int main ()
{
unsigned char *buffer1;
unsigned char *buffer2;
unsigned char *buffer3;
long size1;
long size2;
long tot_byteoffsets = 0;
ifstream file1 (file1, ios::in | ios::binary | ios::ate);
ifstream file2 (file2, ios::in|ios::binary|ios::ate);
size1 = file1.tellg();
size2 = file2.tellg();
file1.seekg (0, ios::beg);
file2.seekg(0, ios::beg);
buffer1 = new unsigned char [size1];
buffer2 = new unsigned char [size2];
buffer3 = new unsigned char [size1];
file1.read(buffer1, size1);
file2.read(buffer2, size2);
file1.close();
file2.close();
// Setup log file
ofstream logfile("logfile.txt");
logfile << "Starting log \n\n" ;
cout << "the complete file is in a buffer" << endl;
cout << "The file size is " << size1 << endl;
cout << "Starting compare" << endl;
//Main comparison loop
int i = 0;
int j = 0;
while (i < size1)
{
if(buffer1[i] == buffer2[j])
{
buffer3[j] = buffer1[i];
i++;
j++;
}
else
{
int bytechange = 0;
logfile << "The following string differs at byte offset " << i << endl;
while((buffer1[i] != buffer2[j]) || (buffer1[i+1] != buffer2[j+1]) ||
(buffer1[i+2]!= buffer2[j+2]))
{
bytechange++;
logfile << (unsigned int*) buffer1[i];
if (bytechange%4 == 0)
logfile << " ";
i++;
}
logfile << "\nTotal bytes - " << bytechange<< endl << endl;
//j++;
tot_byteoffsets += bytechange;
buffer3[j] = buffer1[i];
}
}
//write mpegfile based on comparison
ofstream myFile ("output.mpeg", ios: ut | ios::binary);
myFile.write(buffer3,(size1-tot_byteoffsets));
cout << "Total kilobytes difference is " << (tot_byteoffsets/1024) << endl;
delete[] buffer1;
delete[] buffer2;
delete[] buffer3;
return 0;
}
-
January 21st, 2004, 12:38 AM
#2
if you write in binary file the output will be written in binary form as is the case here.
Regards
-
January 21st, 2004, 12:42 AM
#3
Hi,
The ofstream is not flagged as anything, and the data has to be read into binary for the ifstream but if I do
logfile.hex
the output is the same. Thanks for the hand, do you know how to fix this.
~Steve
-
January 21st, 2004, 02:08 AM
#4
Hi,
The pointer is not required for the unsigned int cast.
logfile<<setbase(16)<<(unsigned int)buffer1[i]<<" ";
Here is some of the output from the log file.
Starting log
The following string differs at byte offset 36
bd 29 40 8 40 4c 1b d9 b e0 2b c4 5a 8e 0 bc 84 82 4a 18 4a 51 50.................
You really need to add checks in your code and make sure it won't result in access violations, particularly in the while loops. I have a feeling that this is a school assignment...am I correct?
TDM
Last edited by TDM; January 21st, 2004 at 06:04 AM.
-
January 21st, 2004, 04:34 AM
#5
This problem had me freak out for quite some time. The problem imho, that the standard c++ library does not make any difference in the implementation of:
Code:
ostream& operator<<( const char );
ostream& operator<<( const unsigned char);
while I believe it should take the first as a character and the second as a short short int.
Here is how I finally solved it. Consider the string s to contain binary data (yes, c++ strings can contain binary data without problems). The "& 0xff" thing might be a bit hacky, but it was what got the whole thing working.
Code:
void hexdump( ostream& o, const string& s )
{
// save the current state of o
const ios::fmtflags old_flags = o.flags();
o << hex;
for ( unsigned long i = 0; i < s.length(); ++i )
o << setw(2) << setfill('0') << (s[i] & 0xff) << ' ';
// restore the old state of o
o.setf( old_flags );
}
-
January 21st, 2004, 08:49 AM
#6
Hi TDM,
Its not a school assignment, I'm just not very good with byte streams. I bought a Creative DVCR TV card, and I shouldn't have skimped ...
It writes a non-standard MPEG stream, that when multiplexed can't be read by windows MPEG demultiplexers. However I found and old MS demultiplexer that I was able to modify to work. Unfortunately, it is very difficult to read the code for the parser, so I am taking the test mpeg stream, running it through the demultiplexer and dumping the output to file. I believe the rules to be easy (and preliminary analysis suggests they are), so this is my way of seeing them. Once I figure out the rules, I'll be able to finish my Directshow filter and be able to write a compliant mpeg2 stream from my (now worthless) card. Thanks for all of your help.
~Steve
P.S. There aren't any violations, although for a more general program, I agree it would be a good idea.
-
January 21st, 2004, 09:56 AM
#7
Looking at the other posts, I am now wondering why I am having such problems with putting out a hexdump of a std::string. Can anybody explain me why the following code
Code:
const unsigned char data[] = { 0, 127, 128, 255 };
for ( unsigned int i = 0; i < 4; ++i )
cout << setbase(16) << (unsigned int)data[i] << ' ';
cout << endl;
const string s( (char*)data, 4 );
for ( unsigned int i = 0; i < 4; ++i )
cout << setbase(16) << (unsigned int)s[i] << ' ';
cout << endl;
gives the following output
0 7f 80 ff
0 7f ffffff80 ffffffff
Thanks for enlightenment.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|