Thread: File reading/writing question

  1. #1
    Registered User Rider's Avatar
    Join Date
    Nov 2005
    Posts
    28

    Question File reading/writing question

    After a disasterous last attempt at programming, I tried my hand at something a little easyer! Namely... Encryption! I'm quite pleased with my current handy-work... but there's something that I don't quite understand.

    The following program (and it's Decrypting counterpart) work fine on .txt and .bmp files... but for some odd reason it mangles .jpg, .exe, .doc and a bunch of other file formats.

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main ()
    {
    
    /*	The following variables are (in order of apearance): 
    	Object for File Input || Object for File Output || Variable to hold the Input Filename || 
    	Variable to hold the Output Filename || Variable for the Current Character || Variable to 
    	put the Encrypted character in || Integer to put the characters ASCII value || Boolean that states 
    	wheter this is the first cycle or not || Integer holding the file size
    */
    	ifstream Fileop;
    	ofstream DestFil;
    	char Filenam[32];
    	char OutFile[32];
    	char c;
    	char e;
    	string ch;
    	int asc;
    	bool firstrun = true;
    	long begin,end;
    
    	cout << "Encryptor\n-----------\nCreated by:Rider Rockon";	// A little bit of interface
    
    	cout << "\n\n\nFile to Encrypt:> ";	
    	cin >> Filenam;				// Wait for input, make Filenam whatever was typed
    	cout << "Destination File:> ";
    	cin >> OutFile;				// Wait for input, make OutFile whatever was typed
    
    cout << "\n Opening Input: " << Filenam << " and Output: " << OutFile << "\n";
    
    	Fileop.open (Filenam);
    	DestFil.open(OutFile,ios::trunc);
    
    	// Count File size & Return the cursor to the start of the file
    	begin = Fileop.tellg();
    	Fileop.seekg (0, ios::end);
    	end = Fileop.tellg();
    	Fileop.seekg (0, ios::beg);
    
    	cout << "Encrypting " << (end-begin) << " bytes of Data...\n";
    
    	while (Fileop.good())	// As long as there's no Error or End of File
    	  {
    
    		ch = "";
    
    		if ( firstrun == false ) 
    		  {
    			// This is where the Encrypting takes place, when done, put it in ch
    			asc = asc + 1; ch = asc;
    	
    			// Write ch to the file
    			DestFil <<  ch;
    		  }
    		else
    		  { firstrun = false; }
    		
    		c = Fileop.get();	// Get the next character in the Input file, put it in c
    		asc = c; 		// asc now contains the ASCII value of c
    	  };
    
    cout << "\nDone...\n";
    Fileop.close();
    DestFil.close();
      return 0;
    }
    I'm still sort of new to all of this and I'm not really sure where the problem is...

    I'd really appreciate any help regarding the subject

  2. #2
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main( int argc, char* argv[] )
    {
    	int m;
    	ifstream MyInFile (argv[1], ios::in | ios::binary);
    	ofstream MyOutFile (argv[2], ios::out | ios::binary);
    	while (MyInFile.good())
    	{
    		MyInFile.read(reinterpret_cast < char * > (&m), sizeof(m));
    		++m;
    		MyOutFile.write(reinterpret_cast < char * > (&m), sizeof(m));
    	}
    	MyInFile.close();
    	MyOutFile.close();
    	return 0;
    }
    Last edited by BobS0327; 12-07-2006 at 11:49 AM.

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Why is this in the C# forum? This is C++.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    So it is. Moved.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  5. #5
    Registered User Rider's Avatar
    Join Date
    Nov 2005
    Posts
    28
    Quote Originally Posted by BobS0327
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
     
    int main( int argc, char* argv[] )
    {
        int m;
        ifstream MyInFile (argv[1], ios::in | ios::binary);
        ofstream MyOutFile (argv[2], ios::out | ios::binary);
        while (MyInFile.good())
        {
            MyInFile.read(reinterpret_cast < char * > (&m), sizeof(m));
            ++m;
            MyOutFile.write(reinterpret_cast < char * > (&m), sizeof(m));
        }
        MyInFile.close();
        MyOutFile.close();
        return 0;
    }
    I'm not quite sure what you're proposing here... I'm still quite new at C++

    The read loop is what confuses me the most... could you elaborate?

    Why is this in the C# forum? This is C++.
    Whoops, my bad.

  6. #6
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    The default file type is non binary or "text". Text files get their newlines converted to CR-LF pairs on write and
    vice versa on read; reading in "text" mode stops at the first ^Z character. Reading binary files as text will
    therefore corrupt the data and fail to read all the data you need. To avoid this, you must call the constructor
    with an explicit ios::binary parameter and use the appropriate functions.

    File streams include two member functions specifically designed to input and output binary data
    sequentially: write and read. The first one (write) is a member function of ostream
    inherited by ofstream. And read is a member function of istream that is inherited by ifstream.

    Although the read and write methods accept a char* pointer, there is no requirement that the data you read
    and/or write be held in a char array. You can read or write any type of data including complex data objects
    using simple type casting of pointers.

    In binary files, to input and output data with the extraction and insertion operators (<< and >>)
    is not efficient, since we do not need to format any data, and data may not use the separation codes
    used by text files to separate elements (like space, newline, etc...).

    Finally, you can place your encryption/decryption routine between the read and write functions, where the ++m
    statement is located. I just used the ++m statement to test the code before posting it. It is not relevant
    for your use and can be deleted.

  7. #7
    Registered User Rider's Avatar
    Join Date
    Nov 2005
    Posts
    28
    Thanks for the help so far! I really appreciate it!

    Just to try out your code bit, I made a small program that simply opens a file, and copies it to another file, character by character.

    It seems like all the file types get converted appropriatly! But it does something odd with a small txt file I tried... it appends "in" to the end... would you have any idea where this might come from?

    I more or less copied your example code... (removing the ++m because it was causing strange corruptions for some reason...)

    Again, any help would be greatly appreciated

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    sizeof int is 4 (on 32 bit systems) so the sample reads and writes 4 bytes at once (or more on some systems)

    You should read and write 1 byte at once,
    use unsigned char for storing it.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > sizeof int is 4 (on 32 bit systems)
    And sizeof(int) is 1 on other 32 bit systems.

    But most newbies are not likely to come across such DSP devices when they're starting.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User Rider's Avatar
    Join Date
    Nov 2005
    Posts
    28
    I'm not sure I"m following...

    does this mean I should declare the char pointer as an unsigned char? Or should I declare the integer m (as the example states) as unsigned?

    And in the case of the former, how do I do this? I'm not very knowledgeable in the field of pointers just yet... I declared this pointer as BobS0327's example stated... in the int main ()...

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    declare m as unsigned char
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Registered User Rider's Avatar
    Join Date
    Nov 2005
    Posts
    28
    Allright! That got rid of the thing... there's only 1 thing wrong now... at the end of a text file, it appends the last character twice.

    I'm sorry to be such a bother, I'm not quite "at home" in C++ just yet

  13. #13
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Rider
    Allright! That got rid of the thing... there's only 1 thing wrong now... at the end of a text file, it appends the last character twice.

    I'm sorry to be such a bother, I'm not quite "at home" in C++ just yet
    It is because the stream test is done before read, not after, so even when the read failed - it still writes the character to the output
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #14
    Registered User Rider's Avatar
    Join Date
    Nov 2005
    Posts
    28
    Ah! Excellent! That solves everything!

    Now I have another question:

    In my original program I converted the char read to an integer (it's ASCII value), did some math with that integer and put it back...

    I've tried a few things, but I can't seem to get the value from char (the pointer) into the integer anymore... and I don't really know how I define the write procedure to... for example... write the string CH (wich is now encrypted) to the new file.

    also... what is EXACTLY going on in the read/write procedure? Would you be so kind as to break down what is going on?

  15. #15
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Hmm....help me take a look at this: File Encryptor
    By heljy in forum C Programming
    Replies: 3
    Last Post: 03-23-2002, 10:57 AM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM