writting a binary in c++ - c++

So i have this program that supposedly reads any file (e.g images, txt) and get its data and creates a new file with that same data. The problem is that i want the data in an array and not in a vector and when i copy that same data to char array, whenever i try to write those bits into a file it doesnt write the file properly.
So the question is how can i get the data from std::ifstream input( "hello.txt", std::ios::binary ); and save it an char array[] so that i can write that data into a new file?
Program:
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <iterator>
#include <vector>
#include <iostream>
#include <algorithm>
int main()
{
FILE *newfile;
std::ifstream input( "hello.txt", std::ios::binary );
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
char arr[buffer.size()];
std::copy(buffer.begin(), buffer.end(), arr);
int sdfd;
sdfd = open("newhello.txt",O_WRONLY | O_CREAT);
write(sdfd,arr,strlen(arr)*sizeof(char));
close(sdfd);
return(0);
}

Try this:
(It basically uses a char*, but it's an array here. You probably can't have an array in the stack in this case)
#include <iostream>
#include <fstream>
int main() {
std::ifstream input("hello.txt", std::ios::binary);
char* buffer;
size_t len; // if u don't want to delete the buffer
if (input) {
input.seekg(0, input.end);
len = input.tellg();
input.seekg(0, input.beg);
buffer = new char[len];
input.read(buffer, len);
input.close();
std::ofstream fileOut("newhello.txt");
fileOut.write(buffer, len);
fileOut.close();
// delete[] buffer; u may delete the buffer or keep it for further use anywhere else
}
}
This should probably solve your problem, remember to always have the length (len here) of the buffer if you don't want to delete it.
More here

Related

How to write vector<uint_8> to a file in c++?

I have vector<uint_8> data filled and want to write this data into a file using c++? Tried out but didn't find any reference.
const std::vector<uint8_t> buffer; // let's assume that i'ts filled with values
std::ofstream out("file.txt", std::ios::out | std::ios::binary);
out.write(&buffer, buffer.size());
but not successfull. Also is it correct to open file in binary mode for this?
You can cast the data pointer as recommended by others:
#include <vector>
#include <fstream>
int main()
{
std::vector<uint8_t> temp;
temp.push_back(97);
temp.push_back(98);
temp.push_back(99);
const std::vector<uint8_t> buffer(temp); // let's assume that i'ts filled with values
std::ofstream out("file.txt", std::ios::out | std::ios::binary);
out.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
out.close();
}
Output: file.txt
abc
If you're viewing this via a text file containing binary data (uint8_t), you'll expect to see the following in the file where each uint8_t corresponds with an ascii symbol:
https://www.asciitable.com/
If your intention is to write the integer values to the file instead of the raw binary data, then you would do this instead:
#include <vector>
#include <fstream>
#include <string>
int main()
{
std::vector<uint8_t> temp;
temp.push_back(97);
temp.push_back(98);
temp.push_back(99);
const std::vector<uint8_t> buffer(temp); // let's assume that i'ts filled with values
std::ofstream out("file.txt", std::ios::out | std::ios::binary);
for (auto v : buffer)
{
std::string str = std::to_string(v);
out.write(str.c_str(), str.length());
}
out.close();
}
Output: file.txt
979899

C++ - Read from file to std vector with vector<>.data() using file.read()

I am trying to read data from a file and put it into a vector<unsigned char> using the file.read() method, but something goes wrong.
typedef unsigned char BYTE;
#include <fstream>
#include <string.h>
#include <vector>
#include <iostream>
#include <iterator>
class ROM{
private:
std::vector<BYTE> RomName;
public:
ROM (const char* t_RomFileName){
std::ifstream ROMFile(t_RomFileName, std::ifstream::ate | std::ifstream::binary);
RomName.reserve(16);
if (ROMFile.is_open()){
size = ROMFile.tellg();
ROMFile.seekg (80, ROMFile.beg);
ROMFile.read((char*)RomName.data(), 16);
for(std::vector<BYTE>::iterator it = RomName.begin(); it != RomName.end(); ++it ){
std::cout << *it;
}
...
}
};
Nothing is printed on the screen and the RomName.size() returns 0. Also, the file pointer moved of 16 bytes. I tried with char* test = new char[16] and reading in it all works. Where I wrong?

C++ - Strangely formatted hexadecimal output

I'm sure this is a simple question, but I'm trying to output the hexadecimal value of each byte in a file (*.bmp in this case). I have successfully loaded the file in memory, and am able to print hex values of bytes. but when I print certain bytes,When I print certain bytes, for example the 3rd byte (at offset 2), it prints FFFFFFE6, but my hexdump(using HxD) of the file says it is just E6. This happens only on certain bytes, the others print just fine.
Main.cpp is:
#include "main.h"
int main ()
{
ifstream::pos_type size;
char * memblock;
ifstream file ("C:\\hex.bmp", ios::in|ios::binary|ios::ate);
size = file.tellg();
memblock = new char [size];
file.seekg(0, ios::beg);
file.read(memblock, size);
file.close();
printf("%X", memblock[2]);
delete[] memblock;
cin.get();
}
Main.h is:
#ifndef MAIN_H
#define MAIN_H
#include <iostream>
#include <fstream>
#include <stdio.h>
using namespace std;
#endif
You need to understand how variable arguments and standard integral conversions work. When you char is signed, you're in trouble.
Always print bytes as unsigned chars:
char data[100];
printf("%02X", (unsigned char)data[i]);
// ^^^^^^^^^^^^^^^

Extract hexdump or RAW data of a file to text

I was wondering if there is a way to output the hexdump or raw data of a file to txt file.
for example
I have a file let's say "data.jpg" (the file type is irrelevant) how can I export the HEXdump (14ed 5602 etc) to a file "output.txt"?
also how I can I specify the format of the output for example, Unicode or UTF?
in C++
You can use a loop, fread and fprintf: With read you get the byte-value of the bytes, then with fprintf you can use the %x to print hexadecimal to a file.
http://www.cplusplus.com/reference/clibrary/cstdio/fread/
http://www.cplusplus.com/reference/clibrary/cstdio/fprintf/
If you want this to be fast you load whole machine-words (int or long long) instead of single bytes, if you want this to be even faster you fread a whole array, then sprintf a whole array, then fprintf that array to the file.
Maybe something like this?
#include <sstream>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <algorithm>
int main()
{
std::stringstream buffer( "testxzy" );
std::istreambuf_iterator<char> it( buffer.rdbuf( ) );
std::istreambuf_iterator<char> end; // eof
std::cout << std::hex << std::showbase;
std::copy(it, end, std::ostream_iterator<int>(std::cout));
std::cout << std::endl;
return 0;
}
You just have to replace buffer with an ifstream that reads the binary file, and write the output to a textfile using an ofstream instead of cout.
This is pretty old -- if you want Unicode, you'll have to add that yourself.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
unsigned long offset = 0;
FILE *input;
int bytes, i, j;
unsigned char buffer[16];
char outbuffer[60];
if ( argc < 2 ) {
fprintf(stderr, "\nUsage: dump filename [filename...]");
return EXIT_FAILURE;
}
for (j=1;j<argc; ++j) {
if ( NULL ==(input=fopen(argv[j], "rb")))
continue;
printf("\n%s:\n", argv[j]);
while (0 < (bytes=fread(buffer, 1, 16, input))) {
sprintf(outbuffer, "%8.8lx: ", offset+=16);
for (i=0;i<bytes;i++) {
sprintf(outbuffer+10+3*i, "%2.2X ",buffer[i]);
if (!isprint(buffer[i]))
buffer[i] = '.';
}
printf("%-60s %*.*s\n", outbuffer, bytes, bytes, buffer);
}
fclose(input);
}
return 0;
}

Combine big files

I'm trying to join two big files (like the UNIX cat command: cat file1 file2 > final) in C++.
I don't know how to do it because every method that I try it's very slow (for example, copy the second file into the first one line by line)
¿What is the best method for do that?
Sorry for being so brief, my english is not too good
If you're using std::fstream, then don't. It's intended primarily for formatted input/output, and char-level operations for it are slower than you'd expect. Instead, use std::filebuf directly. This is in addition to suggestions in other answers, specifically, using the larger buffer size.
Use binary-mode in the standard streams to do the job, don't deal with it as formatted data.
This is a demo if you want transfer the data in blocks:
#include <fstream>
#include <vector>
std::size_t fileSize(std::ifstream& file)
{
std::size_t size;
file.seekg(0, std::ios::end);
size = file.tellg();
file.seekg(0, std::ios::beg);
return size;
}
int main()
{
// 1MB! choose a conveinent buffer size.
const std::size_t blockSize = 1024 * 1024;
std::vector<char> data(blockSize);
std::ifstream first("first.txt", std::ios::binary),
second("second.txt", std::ios::binary);
std::ofstream result("result.txt", std::ios::binary);
std::size_t firstSize = fileSize(first);
std::size_t secondSize = fileSize(second);
for(std::size_t block = 0; block < firstSize/blockSize; block++)
{
first.read(&data[0], blockSize);
result.write(&data[0], blockSize);
}
std::size_t firstFilerestOfData = firstSize%blockSize;
if(firstFilerestOfData != 0)
{
first.read(&data[0], firstFilerestOfData);
result.write(&data[0], firstFilerestOfData);
}
for(std::size_t block = 0; block < secondSize/blockSize; block++)
{
second.read(&data[0], blockSize);
result.write(&data[0], blockSize);
}
std::size_t secondFilerestOfData = secondSize%blockSize;
if(secondFilerestOfData != 0)
{
second.read(&data[0], secondFilerestOfData);
result.write(&data[0], secondFilerestOfData);
}
first.close();
second.close();
result.close();
return 0;
}
Using plain old C++:
#include <fstream>
std::ifstream file1("x", ios_base::in | ios_base::binary);
std::ofstream file2("y", ios_base::app | ios_base::binary);
file2 << file1.rdbuf();
The Boost headers claim that copy() is optimized in some cases, though I'm not sure if this counts:
#include <boost/iostreams/copy.hpp>
// The following four overloads of copy_impl() optimize
// copying in the case that one or both of the two devices
// models Direct (see
// http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)
boost::iostreams::copy(file1, file2);
update:
The Boost copy function is compatible with a wide variety of types, so this can be combined with Pavel Minaev's suggestion of using std::filebuf like so:
std::filebuf file1, file2;
file1.open("x", ios_base::in | ios_base::binary);
file2.open("y", ios_base::app | ios_base::binary);
file1.setbuf(NULL, 64 * 1024);
file2.setbuf(NULL, 64 * 1024);
boost::iostreams::copy(file1, file2);
Of course the actual optimal buffer size depends on many variables, 64k is just a wild guess.
As an alternative which may or may not be faster depending on your file size and memory on the machine. If memory is tight, you can make the buffer size smaller and loop over the f2.read grabbing the data in chunks and writing to f1.
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
ofstream f1("test.txt", ios_base::app | ios_base::binary);
ifstream f2("test2.txt");
f2.seekg(0,ifstream::end);
unsigned long size = f2.tellg();
f2.seekg(0);
char *contents = new char[size];
f2.read(contents, size);
f1.write(contents, size);
delete[] contents;
f1.close();
f2.close();
return 1;
}