CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jun 2003
    Posts
    258

    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;
    }

  2. #2
    Join Date
    Dec 2003
    Posts
    99
    if you write in binary file the output will be written in binary form as is the case here.

    Regards

  3. #3
    Join Date
    Jun 2003
    Posts
    258
    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

  4. #4
    Join Date
    Jan 2004
    Location
    Earth
    Posts
    567
    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.

  5. #5
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401
    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 );
    }

  6. #6
    Join Date
    Jun 2003
    Posts
    258
    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.

  7. #7
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401
    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
  •  





Click Here to Expand Forum to Full Width

Featured