Thread: Writting hex value into files

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jul 2010
    Posts
    56

    Writting hex value into files

    I cant figure out how to make this damn code work.
    Its objective is simple: the user selects a file, type the offset and then the hex value he wants to be put in that specifit offset. This is what i came up with so far:

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        string fileName;
        int offset;
        string hexValue;
    
        cout<<"FILE: ";
        cin>>fileName;
    
        fstream myFile(fileName);
    
        if(myFile.is_open())
        {
            cout<<"OFFSET: ";
            cin>>offset;
    
            cout<<"HEX VALUE TO BE WRITTEN: ";
            cin>>hexValue;
    
            myFile.seekp(offset);
            myFile.write(hexValue,1);
        }
        else
        cout<<"Couldn't open file!"<<endl;
    
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Jul 2010
    Posts
    56
    Bump

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Well it sounds like you want to use a binary file to me. Put the whole file in a string, and edit it in the way you described. Then write() your new binary file when you're done.

  4. #4
    Registered User
    Join Date
    Jul 2010
    Posts
    56
    Well it sounds like you want to use a binary file to me. Put the whole file in a string, and edit it in the way you described. Then write() your new binary file when you're done.
    Isn't every file considered binary?
    Let's say I follow your advice and put the whole file in a string, how could i edit a specific character and replace it with a hex value (not a ascii character), how can this be done? (arent strings suppose to deal with ascii only?)

    btw thanks for answering

  5. #5
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    Yes, all files saved on the hard drive in their most basic form are binary, but in this context we mean how you are opening the file. Using fstream you can open a file as a text stream or alternatively you can open it in binary format. I'm not going to go into the details of each of them because there are plenty of tutorials on the internet which discusses each 'mode' in detail.

    What I will say is that you are opening a file using fstream in text mode but then using write() as though it was a binary file. If you want to write a file in binary format you need to specify 'fstream::binary' when you use open it. (fstream open method reference). Then you would just save the data using the write() method.

    Another alternative is that you stick to keeping the file in text mode, in which case you could write the data in hex format by using using the overloaded operators, '<<' & '>>' to read and write to the stream but you would have to use the manipulator first so that it comes out in hexadecimal format.

    Click me for more information.

    Example code of using the operators to output in Hex:
    Code:
    n = 65;               /* If typecast to char, that would be the character 'A' */
    file << hex << n << std::endl;
    Last edited by Swarvy; 11-02-2010 at 12:32 PM.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >>(arent strings suppose to deal with ascii only?)
    Yes and no. Yes, because you wouldn't be able to use unsigned chars in std::string without changing the char traits (which you can do, but vector<unsigned char> is also a comfortable alternative). No, because a string is a sequence of characters, one character == one byte, and unsigned char gives you the full range of values for a single byte. If you're using hexadecimal because you're working with bits, then that should be enough.

    If you have the whole file contained in an array like structure, then the offset is the subscript you would use.

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    The first parameter to ofstream.write() is a const char * you are trying to write an integer. See this link write

    You might be better off using ofstream.put() See this link put. Which puts a char onto the stream.

    Jim

  8. #8
    Registered User
    Join Date
    Jul 2010
    Posts
    56
    I still havent figured out how to write hex value to the file...

    here's what i tried:

    Code:
    myFile.put(0xFF,1);
    i only accepts char type data as argument...

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You will need to cast the int 0xFF to a char * in order to use write.



    Code:
       int x = 0xFF;
       myFile.write ((char*)&x, sizeof (x));

    Jim

  10. #10
    Registered User
    Join Date
    Jul 2010
    Posts
    56
    Another question, why can't the fstream constructor accept a string as the filename?

    Here's what I tried:

    Code:
        string fileName;
        cout<<"FILE:";
        cin>>fileName;
        fstream myFile(fileName,ios::in | ios::out | ios::binary);
    Compiler error:

    Code:
    no matching function for call to `std::basic_fstream<char, std::char_traits<char> >::basic_fstream(std::string&, std::_Ios_Openmode)'|

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by dhuan
    Another question, why can't the fstream constructor accept a string as the filename?
    I cannot authoritatively state the reason why it was not provided with such a constructor, but you should write:
    Code:
    fstream myFile(fileName.c_str(), ios::in | ios::out | ios::binary);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Jul 2010
    Posts
    56
    laserlight, thank you! I could never figure out that the solution to this problem was a simple c_str() function that trasnforms the c++ string into a dummie c char.

    Now, my next question is: how could i make translate a string into a hex value.
    I want to do something like this:

    Code:
    // ... opens a binary file
    
    string hexValue;
    cout<<"Hex value to be put in the file: ";
    cin>>hexValue;
    
    // translate hexValue string into REAL hex values
    
    myFile.write(hexValue);

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    FWIW, this is the results of my tinkering. I think we're at wits end and you need to see, realistically, what you are not doing.

    Code:
    #include <fstream>	// for file api
    #include <vector>	// is string type
    #include <iostream>	// for cout, cin, endl
    #include <iomanip>	// for hex manipulator
    #include <cstdlib>	// for rand ()
    
    #define BYTES 16
    
    int main ()
    {
    	using namespace std;
    
    	fstream dat;
    	// generating data for proof-of-concept
    	dat.open ("dump.dat", ios::out | ios::binary);
    	if (dat.is_open()) 
    	{
    		char byte;
    		for (int i = 0; i < BYTES; i++) 
    		{
    			byte = (rand () % 99) & 0xff;
    			cout << "writing value 0x" << hex << int(byte) << endl;
    			dat.write (&byte, sizeof byte);
    			if (!dat)
    			{
    				cout << "there was a problem writing the file" << endl;
    				return 0;
    			}
    		}
    		dat.close ();
    	}
    	else 
    	{
    		cout << "buy a bigger hard drive" << endl;
    		return 0;
    	}
    
    	// prove we can read what we wrote
    	vector< char > string (BYTES);
    	dat.open ("dump.dat", ios::in | ios::binary);
    	if (dat.is_open())
    	{
    		dat.read (&string[0], BYTES);
    		if (dat)
    		{
    			for (int i = 0; i < string.size (); i++) {
    				cout << "read value 0x" << hex << int(string[i]) << endl;
    			}
    			dat.close ();
    		}
    		else {
    			cout << "problem reading the file" << endl;
    			return 0;
    		}
    	}
    	
    	// now we edit it
    	vector< char >::size_type offset = 0;
    			
    	cout << "enter the offset:" << endl;
    	cin >> offset;
    	// below statement refers to the exact byte,
    	// while protecting the bounds of string.
    	char &byte = string.at (offset);
    			
    	cout << "enter the byte's new value:" << endl;
    	cin >> hex >> byte;
    
    	// finalize the edit
    	dat.open ("dump.dat", ios::out | ios::binary);
    	if (dat.is_open())
    	{
    		dat.write (&string[0], string.size ());
    		if (dat)
    		{
    			for (int i = 0; i < string.size (); i++) {
    				cout << "wrote value 0x" << hex << int(string[i]) << endl;
    			}
    			string.clear ();
    			dat.close ();
    		}
    		else {
    			cout << "problem rewriting the file" << endl;
    			return 0;
    		}
    	}
    	
    	system ("pause");
    
    	// inspect your file -- it works!
    	return 0;
    }
    The example has challenges. Chiefly, because I don't know how to tell my present compiler to treat char as unsigned char, I definitely couldn't tell you how to do that with your software even if we both had the same compiler. So the output may look different, depending on the inputs, because of char being signed. If the appropriate switch were turned on, then the fact that this works would be much more apparent. I apologize for my ignorance. I also don't buy that you are just editing random bytes, and that there is a decent chance your file is record based, but I went and showed that you can indeed edit random bytes. If you were doing this with a record based file, then you would read the raw input into an instance of the very class that you saved instead of a string. The bit-fiddling part would have to be done on the class members and then re-saved.

    Unless the file is really big, don't bother seeking it.
    Last edited by whiteflags; 11-03-2010 at 11:49 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Create Copies of Files
    By Kanshu in forum C++ Programming
    Replies: 13
    Last Post: 05-09-2009, 07:53 AM
  2. Reading .dat files from a folder in current directory...
    By porsche911nfs in forum C++ Programming
    Replies: 7
    Last Post: 04-04-2009, 09:52 PM
  3. Linking header files, Source files and main program(Accel. C++)
    By Daniel Primed in forum C++ Programming
    Replies: 3
    Last Post: 01-17-2006, 11:46 AM
  4. Multiple Cpp Files
    By w4ck0z in forum C++ Programming
    Replies: 5
    Last Post: 11-14-2005, 02:41 PM
  5. Folding@Home Cboard team?
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 398
    Last Post: 10-11-2005, 08:44 AM