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]);
// ^^^^^^^^^^^^^^^
Related
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
I've been trying to interpret an ar(the libglib-2.0.a) file using this struct here declared in ar.h. Acording to the wiki the ending characters shoud be 0x60 and 0x0A, but what I got is 0x35 and 0x34, in fact the ending characters are actually 8 bytes ahead in the stream!
Here's the code:
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <elf.h>
#include <ar.h>
int main(){
int fd = open("libglib-2.0.a", O_RDONLY);
char b[1000];
read(fd, b, 1000);
ar_hdr *arS = (ar_hdr*) b;
int dummy = 0;
}
Am I missing something?
First of all, you miss the 8 bytes offset at the top.
#define ARMAG "!<arch>\n" /* String that begins an archive file. */
#define SARMAG 8 /* Size of that string. */
Then, you create a buffer of a bizarre size — 1000. That value makes absolutely no sense, we have a correct buffer size for it, which is the size of header itself — we know it statically, it's 60 bytes. Not to mention that to interpret the buffer as a correct struct, memory representation should be properly aligned.
Here's a working example, for the sake of brevity, error-checking is omitted.
#include <stdio.h>
#include "unistd.h"
#include <fcntl.h>
#include <string.h>
#include "ar.h"
int main() {
int fd = open("/usr/lib/libc.a", O_RDONLY);
lseek(fd, SARMAG, SEEK_SET);
ssize_t bufSize = sizeof(struct ar_hdr);
char buf[bufSize];
read(fd, buf, bufSize);
struct ar_hdr header;
memcpy(&header, buf, bufSize);
printf("\%02hhx, \%02hhx\n", header.ar_fmag[0], header.ar_fmag[1]);
return 0;
}
$ ./read
60, 0a
So I have written a small program that reads the contents of a file into a char array(because fstream seems to only support char pointers). What I want to do is send the raw bytes to the console. AFAIK char is an 8 bit data type so it should not be too hard.
However if I just print members of the array, I get the characters corresponding to the ASCII values, so I am using a static cast. This works fine, except the first byte does not seem to get cast properly.
I am using a PNG file as the test.bin file. PNG files always begin with the byte sequence of 137,80,78,71,13,10,26,10. However the fist byte is printed incorrectly. I have a feeling it has to do something with the value being over 127. However, I cannot change the read buffer data type to anything else (like unsigned char, or unsigned short int), because foo.read() from fstream only supports char destination buffers.
How do I get fstream to read the raw bytes into a usable unsigned type?
My code:
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#define filename "test.bin"
void pause(){
std::string dummy;
std::cout << "Press enter to continue...";
std::getline(std::cin, dummy);
}
int main(int argc, char** argv) {
using std::cout;
using std::endl;
using std::cin;
// opening file
std::ifstream fin(filename, std::ios::in | std::ios::binary);
if (!fin.is_open()) {
cout << "error: open file for input failed!" << endl;
pause();
abort();
}
//getting the size of the file
struct stat statresults;
if (stat(filename, &statresults) == 0){
cout<<"File size:"<<statresults.st_size<<endl;
}
else{
cout<<"Error determining file size."<<endl;
pause();
abort();
}
//setting up read buffer and reading the entire file into the buffer
char* rBuffer = new char[statresults.st_size];
fin.read(rBuffer, statresults.st_size);
//print the first 8 bytes
int i=0;
for(i;i<8;i++) {
cout<<static_cast<unsigned short>(rBuffer[i])<<";";
}
pause();
fin.clear();
fin.close();
delete [] rBuffer;
pause();
return 0;
}
-119 signed is 137 unsigned (both are 1000 1001 in binary).
This gets sign-extended into the short 1111 1111 1000 1001, which is 65,417 unsigned.
I assume this is the value you're seeing.
To read into an unsigned buffer:
unsigned char* rBuffer = new unsigned char[statresults.st_size];
fin.read(reinterpret_cast<char*>(rBuffer), statresults.st_size);
How about trying something other than fin.read()?
Instead of:
char* rBuffer = new char[statresults.st_size];
fin.read(rBuffer, statresults.st_size);
You could use:
unsigned char* rBuffer = new unsigned char[statresults.st_size];
for(int i = 0; i < statresults.st_size; i++)
{
fin.get(rBuffer[i]);
}
You likely want to be using unsigned char as your "byte". You could try something like this:
using byte = unsigned char;
...
byte* buffer = new byte[statresults.st_size];
fin.read( reinterpret_cast<char*>( buffer ), statresults.st_size );
...
delete[] buffer;
I am trying to get some chars read from a file and into a string. For example #2%4$$3. My program will take out 243 from the text file, now I need it to be in a string so I can convert it to two hundred and 43 and given to an INT var.
Any help would be Superbly appreciated! :)
Thanks,
Brian
Try this program
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char file_buff[1024]="!#25#3$#4";
char num_buff[1024];
int len,i,k;
// open file and read the entire contents specied as per the size
FILE *f = fopen("file.txt", "r");
fgets(file_buff, 1024, f);
printf("String read: %s\n", file_buff);
fclose(f);
len=strlen(file_buff);
// parse the buffer for digits and store it in a buffer
for(i=0,k=0;i<len;i++)
{
if((file_buff[i] >= 0x30) && (file_buff[i] <= 0x39))
{
num_buff[k]=file_buff[i];
k++;
}
}
num_buff[k]='\0';
printf("%s",num_buff);
return 0;
}
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;
}