I am trying to write a function that reads specified number of bytes from a binary file and converts them into a string of 1's and 0's. What is the easiest way to do that.
File is in BigEndian.
string ReadBytesFromFile(int size)
{
string result;
ifstream file ("example.bin", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
//need to convert memblock to binary string
result = GetBinaryString(memblock);
delete[] memblock;
}
return result;
}
Call itoa() passing 2 as the radix. Make sure you don't overrun your buffer!
Note: This isn't part of any C or C++ standard so be warned it is not portable. But you asked for ease rather than portability!
Take a byte at a time, and shift the bits off one by one.
Something like:
std::ostringstream ss;
for (int i=0; i<size; ++i) {
char byte = memblock[i];
for (int j=0; j<8; ++j) {
ss << byte & 1;
byte = byte << 1;
}
}
Related
I am trying to separate a 5 KB text file into a File array of 10 blocks, which are each 512 Bytes.
I have the file loading properly and writing to a char array but I don't understand what is happening at while(infile >> temp[i]) below. Does that mean "while test1.txt still has characters to write, write it to temp[]"?
Basically, I want characters 0 to 511 in input1.txt to load into temp[] then store temp in fileArray[0]. And then characters 512 to 1023 to load into temp[] and then be stored into fileArray[1] and so on. If the file is shorter than 5 KB, fill the rest of the items in fileArray[] with 0's.
Code:
FILE* fileArray[10];
//something like for(int a = 0; a < fileArray.length; a++)
ifstream infile;
int i = 0;
int k = 0;
char temp[512];
infile.open("inputFiles/test1.txt"); //open file in read mode.. IF FILE TOO BIG, CRASHES BECAUSE OF TEMP
while (infile >> temp[i])//WHAT DOES THIS MEAN?
i++;
k = i;
for (int i = 0; i < k; i++) {
cout << temp[i]; //prints each char in test1.txt
}
New Code:
FILE* input = fopen(filename, "r");
if (input == NULL) {
fprintf(stderr, "Failed to open %s for reading OR %s is a directory which is fine\n", filename, filename);
return;
}
FILE **fileArray = (FILE**) malloc(10 * 512); //allow files up to 5.12KB (10 sectors of 512 Bytes each)
//load file into array in blocks of 512B
//if file is less than 5.12KB fill rest with 0's
std::filebuf infile;
infile.open("inputFiles/test1.txt", std::ios::in | std::ios::binary);
for (int a = 0; a < 10; a++) {
outfile.open(fileArray[a], std::ios::out | std::ios::binary);
int block = 512 * a;
int currentBlockPosition = 0;
while (currentBlockPosition < 512) {
std::copy(std::istreambuf_iterator<char>(&infile[block + currentBlockPosition]), {},
std::ostreambuf_iterator<char>(&outfile));
//input[block * currentBlockPosition] >> fileArray[a];
//currentBlockPosition++;
}
}
while (infile >> temp[i])//WHAT DOES THIS MEAN?
i++; // This is means while there exist data in the file put this data in temp array
and I think it is good idea to take the whole data from the file and then split array
I have below code :
/*write to file*/
std::basic_ofstream<unsigned short> out(path, std::ios::out);
unsigned short *arr = new unsigned short[500];
for (int i = 0; i < 500; i++)
{
arr[i] = i;
}
out.write(arr, 500);
out.close();
/*read from file*/
unsigned short * data = new unsigned short[500];
std::basic_ifstream<unsigned short> rfile(path);
rfile.read(data, 500);
rfile.close();
Simply i write a unsigned short array to file then i read that but read values are right until index 25 in array and after that the values are 52685.
Where is the problem?
First of all, don't use the template parameter of basic_ofstream with a non character type (i.e. char, wchar_t, char16_t or char32_t). For the most part, just use ofstream (and ifstream for input).
The fact that your input stops after the 25th character is actually a clue that you are probably on Windows, where ASCII character 26, the Substitute character, is used to indicate end of file for text streams. You are trying to read and write binary data though, so you need to open your file with the binary flag.
/*write to file*/
std::ofstream out(path, std::ios::binary);
unsigned short *arr = new unsigned short[500];
for (int i = 0; i < 500; i++) {
arr[i] = i;
}
out.write((char const*)arr, 500 * sizeof(arr[0]));
out.close();
/*read from file*/
unsigned short * data = new unsigned short[500];
std::ifstream rfile(path, std::ios::binary);
rfile.read((char*)data, 500 * sizeof(data[0]));
rfile.close();
Also interesting to note, 52685, in hexadecimal is 0xCDCD. This is the value which Visual C++ (and maybe some other compilers) uses to fill uninitialized memory in debug mode. Your array isn't receiving this value from the file, this is the value which was inserted there when your memory was allocated.
This is a frequently question but I could not find appropriate answer.
I have a char array containing HEX values. I need to write this array in a text file "as a string".
My understanding of HEX not being stored in the files (looked garbage data) was flawed. In Hex editor I could see the data.
My Hex array is actually integer array and not characters. This I need to take into consideration.
I tried this:
FILE * out = fopen(out_file_name, "w");
char *in = (char*)malloc(sizeof(char) * num_encryption * 16);
....
fwrite(in, sizeof(char), num_encryption*16 + 1, out);
I also tried stream but it again prints garbage in text files.
The in array contains the HEX strings like this: 21c169ea622e7d52ecd35423f4c3c9f4, and there are 32 lines (num_encryption=32) in total.
I also tried something like this:
std::ofstream outfile(argv[21]);
if(outtfile.is_open()){
//outtfile.write(wo, sizeof(char)*(num_encryption*16+1));
for(int k = 0; k < num_encryption; k++){
for(int j = 0; j < 16; ++j){
outfile << static_cast<unsigned char>(wo[j + k*16] & 0xff);
}
outtfile << std::endl;
}
}
Even the commented part did not work properly.
Any suggestions?
Solution
I just redirected the output (which was fine) to the file:
FILE * out = fopen(out_file_name, "w");
for(int k = 0; k < num_encryption; k++){
for(int j = 0; j < 16; ++j){
fprintf(outfile, "%02x", wo[j + k*16] & 0xff);
}
fprintf(outfile, "\n");
}
fclose(outfile);
I am not sure if this is the most elegant solution,but it works for me. If you know anything better then please add here.
If the question is about C++ also, let me give you advice on how to use features superseded by C++. You are using C-style features.
You should use iostreams. Avoid malloc, use new, but, even better, use a vector<char> or unique_ptr<char[]> directly. In this case I will use unique_ptr<char[]> since it seems you do not need to resize the array. I assume you want to write a binary file below.
//I assume you want a binary file
std::ostream file("myfile.txt", std::ios::binary);
std::unique_ptr<char []> in = std::unique_ptr<char []>(new char[num_encryption * 16]);
if (file)
file.write(in.get(), sizeof(char) * num_encryption * 16);
If you want, instead, write text data in hex, open the file in text mode:
std::ostream file("myfile.txt"); //Note, no std::ios::binary
...
file >> std::hex >> std::noshowbase; //Write in hex with no base
std::copy(in.get(),
in.get() + num_encryption * 16,
std::ostream_iterator<char>(file)); //Write one char at a time, in hex, with no base
WARNING: Not tested, just shown the idea on how to write binary or formatted hex text, char by char.
I am stumped and need some assistance.
In one of my programs, I am implementing some code so that I can take a program on Windows and essentially do a hexdump (what you see in hex editors) where I convert it to binary and write that to a .txt document. I just recently got that half figured out. The other half of the code is to rebuild an object that has been dumped to binary in .txt file into the original object. This should work for all objects in general and not just rebuilding one certain object.
Partial Code for Dumping Part:
//Rip Program to Binary
streampos size; //Declare size variable
unsigned char* memblock; //Holds input
ifstream input; //Declare ifstream
ofstream output("output.txt", ios::out|ios::binary); //Specify ofstream
input.open("sparktools.bin", ios::in|ios::binary|ios::ate); //Open input file and move to the end of it
size = input.tellg(); //Store current location as file length
memblock = new unsigned char [size]; //Declare the input holder with array size as length of file
input.seekg (0, ios::beg); //Return to beginning of file
input.read((char*)memblock, size); //Read each character of the input file until end of file
for (int i=0; i<size; i++) //For each character until end of file:
{
std::bitset<sizeof(char) * CHAR_BIT> binary(memblock[i]); //Set bitset<1> to essentially convert to a binary char array
output << binary; //Output from binary variable created
}
input.close();
output.close();
delete[] memblock;
Partial Code for Rebuilding Part:
//Restore Ripped Binary To Program
int size; //Holds length of input document
unsigned char* memblock; //Holds input
ifstream input; //Declare ifstream
ofstream output("Binary.bin", ios::out|ios::binary); //Specify ofstream
input.open("Binary.txt", ios::in|ios::binary|ios::ate); //Open input file and move to the end of it
size = input.tellg(); //Store current location as file length
input.seekg(0, ios::beg); //Return to beginning of file
memblock = new unsigned char [size]; //Declare the input holder with array size as length of file
input.read((char*)memblock, size); //Read each character of the input file until end of file
for (int i=0; i<size; i++) //For each character until end of file:
{
output.write((char*) &memblock[i], size); //Write each char from the input array one at a time until end of file to the output binary
}
input.close();
output.close();
delete[] memblock;
I am testing the capabilities on an image. The original filesize is 10 KB. When dumped, the .txt file is 76 KB and the contents match what shows in a hex editor.
When I am rebuilding from the binary dump, the filesize will not go back to 10 KB. When I up the bitset number, the file size increases. However, at bitset<1> it stays at 76 KB. From my conclusion, I essentially need bitset <0.125> to reduce the filesize from 76KB back down to 10 KB and the numbers should match up and it can simply be renamed from .bin to .whatever-it-originally-was and function correctly. However I don’t think bitset goes below 1.
Code I have tried:
43555 KB: output.write((char*)&memblock[i], size);
0 KB: output.write((char*)memblock[i], size);
43555 KB: output.write((const char*)&memblock[i], size);
43555 KB: output.write(reinterpret_cast<const char*>(&memblock[i]), size);
43555 KB: output.write(reinterpret_cast<char*>(&memblock[i]), size);
76 KB: output << memblock[i];
When I do these simple checks:
cout << memblock[i];
cout << size;
I am seeing that all of the input has been read in and is identical to what is in the file. The size variable is correct at 77296.
From doing some guesswork, I think I need to do something with bitset or else manually convert from bits back to bytes, convert, and then pass that value on to accomplish this. Am I on the right path or is there a better/easier way/something wrong in my code? Thanks in advance for the help!
As far as I can tell the problem is the bit order in the dump of the bitset, the disk dump from the first fragment of code:
11001010
means that the first bit is the most significant of the byte, so to decode this you should do in the loop something like this (tested):
unsigned char *p = memblock;
//For each character until end of file:
for (int i=0; i<size/8; i++)
{
uint8_t byte = 0;
for (int j = 7; j >= 0; j--)
if (*p++ == '1')
byte |= (1 << j);
output.write((char*) &byte, 1);
}
Note that you cycle size/8 since every 8 chars encode a byte and the fact that the inner loop iterates from 7 to 0 to reflect the fact that the first bit is the more significant.
I have char array, and i want to write it to txt file, but in bytes.
ofstream sw("C:\\Test.txt");
for(int i = 0; i < 256; i++)
{
sw << (byte)myArray[i];
}
This will write chars into the file, but i want to write bytes. If there is char 'a' i want to write '97'. Thank you.
To write a byte or a group of bytes using std::fstream or std::ofstream, you use the write() function: std::ostream::write()
const int ArraySize = 100;
Byte byteArray[ArraySize] = ...;
std::ofstream file("myFile.data");
if(file)
{
file.write(&byteArray[0], ArraySize);
file.write(&moreData, otherSize);
}
ofstream sw("C:\\Test.txt");
for(int i = 0; i < 256; i++)
{
sw << (int)myArray[i];
}
This will convert a char 'a' to an int(or byte) value 97.