I'm trying to output the plaintext contents of this .exe file. It's got plaintext stuff in it like "Changing the code in this way will not affect the quality of the resulting optimized code." all the stuff microsoft puts into .exe files. When I run the following code I get the output of M Z E followed by a heart and a diamond. What am I doing wrong?
ifstream file;
char inputCharacter;
file.open("test.exe", ios::binary);
while ((inputCharacter = file.get()) != EOF)
{
cout << inputCharacter << "\n";
}
file.close();
I would use something like std::isprint to make sure the character is printable and not some weird control code before printing it.
Something like this:
#include <cctype>
#include <fstream>
#include <iostream>
int main()
{
std::ifstream file("test.exe", std::ios::binary);
char c;
while(file.get(c)) // don't loop on EOF
{
if(std::isprint(c)) // check if is printable
std::cout << c;
}
}
You have opened the stream in binary, which is good for the intended purpose. However you print every binary data as it is: some of thes characters are not printable, giving weird output.
Potential solutions:
If you want to print the content of an exe, you'll get more non-printable chars than printable ones. So one approach could be to print the hex value instead:
while ( file.get(inputCharacter ) )
{
cout << setw(2) << setfill('0') << hex << (int)(inputCharacter&0xff) << "\n";
}
Or you could use the debugger approach of displaying the hex value, and then display the char if it's printable or '.' if not:
while (file.get(inputCharacter)) {
cout << setw(2) << setfill('0') << hex << (int)(inputCharacter&0xff)<<" ";
if (isprint(inputCharacter & 0xff))
cout << inputCharacter << "\n";
else cout << ".\n";
}
Well, for the sake of ergonomy, if the exe file contains any real exe, you'd better opt for displaying several chars on each line ;-)
Binary file is a collection of bytes. Byte has a range of values 0..255. Printable characters that can be safely "printed" form a much narrower range. Assuming most basic ASCII encoding
32..63
64..95
96..126
plus, maybe, some higher than 128, if your codepage has them
see ascii table.
Every character that falls out of that range may, at least:
print out as invisible
print out as some weird trash
be in fact a control character that will change settings of your terminal
Some terminals support "end of text" character and will simply stop printing any text afterwards. Maybe you hit that.
I'd say, if you are interested only in text, then print only that printables and ignore others. Or, if you want everything, then maybe write them out in hex form instead?
This worked:
ifstream file;
char inputCharacter;
string Result;
file.open("test.exe", ios::binary);
while (file.get(inputCharacter))
{
if ((inputCharacter > 31) && (inputCharacter < 127))
Result += inputCharacter;
}
cout << Result << endl;
cout << "These are the ascii characters in the exe file" << endl;
file.close();
Related
int main(){
std::cout << "Insert file name / or path. \n NOTE: ONLY INPUTS. DELETES PREVIOUS DATA.\nV.6" << std::endl;
std::string filen;
std::cin >> filen;
std::ofstream myFile;
try{
myFile.open(filen, std::ios::out);
}
catch(std::fstream::failure){
std::cout << "Could not open file!\n Make sure the name and data type are valid.";
system("pause");
}
while(true){
int press = getch();
if(press == 43) myFile.close();
if(press == 8){myFile << "\b" << " " << "\b";std::cout << "\b" << " " << "\b" << std::flush;}
if(press == 13){ myFile << "\n"; std::cout << "\n" << std::flush;}
if(press != 43 && press != 127 && press != 13 && press != 8){myFile << (char)press;std::cout << (char)press;}
}
return 0;
}
Whenever I choose a text file and I press backspace, and I check the document and when I check the text document, I get random characters like so:
Those are not "random characters"; those are backspace characters! i.e. exactly the input you gave.
This can be verified with a hex editor (or piping the output of your program through hexdump et al).
If you wish to replicate the behaviour of common shells, you'll have to write your own code to identify the backspace character and, instead of appending it to myFile, instead eliminate the previously-entered character.
As #BoundaryImposition pointed out already, writing "\b" to your file, will actually write a binary backspace character to your file. What you probably want instead is myFile.seekp(-1, std::ios_base::cur);. If you are on win/dos machine you likely need extra care with '\n' characters because they are translated into 0x0d 0x0a when written to a text stream (thus they require to seek back 2 positions instead of 1).
But generally, if you are not dealing with very huge files, it will be way easier to just store the content in a std::string (using pop_back or erase, to remove characters if needed) and write it to the file when you are finished.
I am working on a C++ project and I am having an issue.
Below is my code
tempfingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_TYPE_RSA);
char temp[48];
memset(temp, 0, sizeof(temp));
for (i = 0; i < 16; i++)
{
//fingerprintstream << (unsigned char)tempfingerprint[i] << ":";
if (temp[0] == 0)
{
sprintf(temp, "%02X:", (unsigned char)tempfingerprint[i]);
}
else
{
//sprintf(temp, "%s:%02X", temp, (unsigned char)tempfingerprint[i]);
char characters[3];
memset(characters, 0, sizeof(characters));
//If less than 16, then add the colon (:) to the end otherwise don't bother as we're at the end of the fingerprint
sprintf(characters, "%02X:", (unsigned char)tempfingerprint[i]);
strcat(temp, characters);
}
}
//Remove the end colon as its not needed. 48 Will already be null terminated, so the previous will contain the last colon
temp[47] = 0;
return string(temp);
When I run my app, I get the following error from visual studio
Run-Time-Check Failure #2 - Stack around the variable 'temp' was corrupted.
I've ran the same code on Linux through Valgrind and no errors were shown so I'm not sure what the problem is with Windows.
Here's an approach using on what Paul McKenzie's talking about (though he might implement it differently) based on it looks like you were trying to do with the stream
#include <iostream>
#include <sstream>
#include <iomanip> // output format modifiers
using namespace std;
int main()
{
stringstream fingerprintstream;
// set up the stream to print uppercase hex with 0 padding if required
fingerprintstream << hex << uppercase << setfill('0');
// print out the first value without a ':'
fingerprintstream << setw(2) << 0;
for (int i = 1; i < 16; i++) // starting at 1 because first has already been handled.
{
// print out the rest prepending the ':'
fingerprintstream << ":" << setw(2) << i;
}
// print results
std::cout << fingerprintstream.str();
return 0;
}
Output:
00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F
Just realized what I think OP ran up against with the garbage output. When you output a number, << will use the appropriate conversion to get text, but if you output a character << prints the character. So fingerprintstream << (unsigned char)tempfingerprint[i]; takes the binary value at tempfingerprint[i] and, thanks to the cast, tries to render it as a character. Rather than "97", you will get (assuming ASCII) "a". A large amount of what you try to print will give nonsense characters.
Example: If I change
fingerprintstream << ":" << setw(2) << i;
to
fingerprintstream << ":" << setw(2) << (unsigned char)i;
the output becomes
0?:0?:0?:0?:0?:0?:0?:0?:0?:0?:0 :0
:0?:0?:0
:0?:0?
Note the tab and the line feeds.
I need to know the definition of tempfingerprint to be sure, but you can probably solve the garbage output problem by removing the cast.
Based on new information, tempfingerprint is const char *, so tempfingerprint[i] is a char and will be printed as a character.
We want a number, so we have to force the sucker to be an integer.
static_cast<unsigned int>(tempfingerprint[i]&0xFF)
the &0xFF masks out everything but the last byte, eliminating sign extension of negative numbers into huge positive numbers when displayed unsigned.
There are, as far as I see, two issues in the code which lead to exceeding array boundaries:
First, with char temp[48] you reserve exactly 48 characters for storing results; However, when calling strcat(temp, characters) with the 16th value, and characters comprises at least the characters including the colon, then temp will comprise 16*3 digits/colons + one terminating '\0'-character, i.e. 49 characters (not 48). Note that strcat automatically appends a string terminating char.
Second, you define char characters[3] such that you reserve place for two digits and the colon, but not for the terminating '\0'-character. Hence, an sprintf(characters, "%02X:",...) will exceed characterss array bounds, as sprintf also appends the string terminator.
So, if you do not want to rewrite your code in general, changing your definitions to char temp[49] and char characters[4] will solve the problem.
Why does my C++ program create the strange character shown below in the pictures? The picture on the left with the black background is from the terminal. The picture on the right with the white background is from the output file. Before, it was a "\v" now it changes to some sort of astrological symbol or symbol to denote males. 0_o This makes no sense to me. What am I missing? How can I have my program output just a backslash v?
Please see my code below:
// SplitActivitiesFoo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
string s = "foo:bar-this-is-more_text#\venus \"some more text here to read.\"";
vector<string> first_part;
fstream outfile;
outfile.open("out.foobar");
for (int i = 0; i < s.size(); ++i){
cout << "s[" << i << "]: " << s[i] << endl;
outfile << s[i] << endl;
}
return 0;
}
Also, assume that I do not want to modify my string 's' in this case. I want to be able to parse each character of the string and work around the strange character somehow.This is because in the actual program the string will be read in from a file and parsed then sent to another function. I guess I could figure out a way to programmatically add backslashes...
How can I have my program output just a backslash v?
If you want a backslash, then you need to escape it: "#\\venus".
This is required because a backslash denotes that the next character should be interpreted as something special (note that you were already using this when you wanted double-quotes). So the compiler has no way of knowing you actually wanted a backslash unless you tell it.
A literal backslash character therefore has the syntax \\. This is the case in both string literals ("\\") and character literals ('\\').
Why does my C++ program create the strange character shown below in the picture?
Your string contains the \v control character (vertical tab), and the way it's displayed is dependent on your terminal and font. It looks like your terminal is using symbols from the traditional MSDOS code page.
I found an image for you here, which shows exactly that symbol for the vertical tab (vt) entry at value 11 (0x0b):
Also, assume that I do not want to modify my string 's' in this case. I want to be able to parse each character of the string and work around the strange character somehow.
Well, I just saw you add the above part to your question. Now you're in difficult territory. Because your string literal does not actually contain the character v or any backslashes. It only appears that way in code. As already said, the compiler has interpreted those characters and substituted them for you.
If you insist on printing v instead of a vertical tab for some crazy reason that is hopefully not related to an XY Problem, then you can construct a lookup-table for every character and then replace undesirables with something else:
char lookup[256];
std::iota( lookup, lookup + 256, 0 ); // Using iota from <numeric>
lookup['\v'] = 'v';
for (int i = 0; i < s.size(); ++i)
{
cout << "s[" << i << "]: " << lookup[s[i]] << endl;
outfile << lookup[s[i]] << endl;
}
Now, this won't print the backslashes. To undo the string further check out std::iscntrl. It's locale-dependent, but you could utilise it. Or just something naive like:
const char *lookup[256] = { 0 };
s['\f'] = "\\f";
s['\n'] = "\\n";
s['\r'] = "\\r";
s['\t'] = "\\t";
s['\v'] = "\\v";
s['\"'] = "\\\"";
// Maybe add other controls such as 0x0E => "\\x0e" ...
for (int i = 0; i < s.size(); ++i)
{
const char * x = lookup[s[i]];
if( x ) {
cout << "s[" << i << "]: " << x << endl;
outfile << x << endl;
} else {
cout << "s[" << i << "]: " << s[i] << endl;
outfile << s[i] << endl;
}
}
Be aware there is no way to correctly reconstruct the escaped string as it originally appeared in code, because there are multiple ways to escape characters. Including ordinary characters.
Most likely the terminal that you are using cannot decipher the vertical space code "\v", thus printing something else. On my terminal it prints:
foo:bar-this-is-more_text#
enus "some more text here to read."
To print the "\v" change or code to:
String s = "foo:bar-this-is-more_text#\\venus \"some more text here to read.\"";
What am I missing? How can I have my program output just a backslash v?
You are escaping the letter v. To print backslash and v, escape the backslash.
That is, print double backslash and a v.
\\v
Background
IIRC, from Release 2.0 C++ stores single-character constants as type char and NOT int. But before Release 2.0 a statement like
cout<<'A'
was problematic as it displays the ASCII value of 'A' ie 65 whereas:
char ch='A';
cout<<ch;
would display the right value ie 'A'.
Since the problem has been rectified in Release 2.0. I believe cout.put() lost the advantage it had over cout<<.
Question
Is there any other reason for recommending cout.put() over cout<< for printing characters?
There are a few differences between cout<< and cout.put, or should we say the overloaded << operator and the put method from std::basic_ostream because this is not really limited to the global instance: cout.
The << operator writes formatted output, the put method does not.
The << operator sets the failbit if the output fails, the put method does not.
Personally I would go with the << operator in almost all cases, unless I had specific needs to bypass the formatted output or not setting the failbit on error.
Using them can result in the following differences of output:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "Character: '" << setw(10) << 'A' << setw(0) << "'" << endl;
cout << "Character: '" << setw(10);
cout.put('A');
cout << setw(0) << "'" << endl;
return 0;
}
Outputs:
Character: ' A'
Character: 'A'
See the above in action: http://ideone.com/9N0VYn
Since the put method is unformatted it does not respect the manipulator set, there might be situations where that is indeed what you intend. But since it sounds like you only want to print out the character, I would prefer the << operator, which respects the formatting.
And then there is the case of the failbit which is not being set, and that might even be more crucial.
I am writing a hex to dec conversion function. The input is a single character which is converted to hex and returned back as a char.
Here is the function
char hex2dec(char inp)
{
char out;
cout << "inp:" << inp;
if(inp >= '0' && inp <='9')
{
out = (inp - '0');
cout << " out " << out;
}
else
{
out = (toupper(inp) - 'A' + 10);
cout << " out " << out;
}
return out;
}
When i pass '0' and 'A' to the function, the print i get is
inp:0 out
inp:A out
i.e nothing is printed in out.
I am not able to find the issue..Can anyone help?
What you are actually trying to print is ascii characters with codes [0-15] which are not printable characters ie you want to print 15 but you print "\x0f" etc
use:
cout << (int)out;
and you'll force cout to invoke method printing ints not chars - this will solve your issue.
..or more 'c++++ ish' ;-)
cout << static_cast(out);
..or this which for most looks weird:
cout << int(out);
Use int out instead of char out. cout prints char as a character not an integer. The ASCII values 0-15 are unprintable control characters.
the reason why u got an 'A' from print is that out is char ,and after 'A' - 'A' + 10, out is a character whose ascii value is 10 instead of integer 10. So u will get a character whose ascii value is 10 instead of getting 'A'.After checking the ascii table, that character is null,which can explain why u get nothing in the output.
Simply use std::stringstream for this purpose.
#include <iostream>
#include <sstream>
int main (int argc, char ** argv)
{
// use hex formatting
std::stringstream stream;
stream << std::hex << 'A';
// retrieve value of the hex input character
int value;
stream >> value;
std::cout << value << std::endl; // prints 10
// reset the stream
stream.str ();
stream.clear();
// also works for strings
stream << "0xABC" << std::endl;
stream >> value;
std::cout << value << std::endl; // prints 2748
return 0;
}