how do I print a binary double array from commandline (unix) - c++

I got binary file, that contains doubles. How do i print that out to a terminal.
I've tried octaldump 'od' but cant figure out the syntax I've tried something like
head -c80 |od -f
But that doesnt work, the man page for od is extremely bad.
I've made a c program that does what I want,
something like assuming 10double chunks.
double tmp[10];
while(fread(tmp,sizeof(double),10,stdin))
for(int i=0;i<10;i++) printf("%f\t",tmp[i]);
thanks.

Have you tried hexdump utility?
hexdump -e ' [iterations]/[byte_count] "[format string]" ' filename
Where format string should be "%f", byte count should be 8, and iterations the amount of floats you want to read

The od command you're looking for is
od -t fD
(That means "floating point values, of double size").

Related

How many bytes will print command output in hex format in GDB?

I'm working on the bomb lab from CMU CSAPP class from this site, the bomb binary is here.
I found a very interesting thing using gdb while i am defusing phase_3 of the bomb. I need to use a lot p/x [MEMORY_ADDRESS] while defusing phase_3, however, the output of the print command looks strange to me.
I tried to print against different memeory address using p/x *[MEMORY_ADDRESS], the length of the output varied a lot. It sometimes gave me a 8-char output like 0x18244c8b, sometimes gave me a 6-char output like 0x28250c, or sometimes only a 0x0.
In my understanding, while using p/x *[MEMORY_ADDRESS], we are only print the hex value of the single byte resides in that memory address, which should only give us a 2-char output in hex format. How does gdb decide how many bytes it will print while executing p/x?
Thanks for looking at this problem.
My understanding is that, gdb is treating my memory address as a pointer to int, thus will always try to print 4 bytes, the reason i'm seeing varying output is because some ouputs have so many leading zeros. So 0xfe is actually 0x000000fe.
In this scenario, gdb's print command is always printing 4 bytes.

How to get the full cmdline that is used to call a program, if the cmdline has multiple pipes

Im writing a framework, to track how people use my utilities, like example utility 'result'
So I want to put in piece of code into result.cxx main() that will log stuff like,
1. what arguments were given to result = argc, argv
2. what other programs were used to process stuff and pipe to my utility 'result'
eg:
Im trying to run a program 'result' which is provided input from pipes like
abc -e earg -t targ | process_stuff_out_data | result -s sarg
now in the result.cxx I use to capture piped input
std::string piped_data;
std::getline(std::cin, piped_data);
this works with cases like
echo "1 2 3 " | result -i in_number
// here the piped input is just "1 2 3" so i am able to log it from result
but wont work for cases where the output from the previous program is a stream of binary data
abc -e earg -t targ | out_bin_data | result -s sarg
In this case i just want to
LOG_PIPED_STUFF: abc -e earg -t targ | process_stuff_out_data
std::getline won't return untill it reads a newline, see here: http://www.cplusplus.com/reference/string/string/getline
Use another separator token or just use another function to read from standard input while the data becomes availible.
You can use for example feof(stdin) to check if stdin has bytes availible and then fread() them.
If you are on linux you can use select(2) to wait for input on file descriptor 0.
Possible reasons you are not getting data
the data is binary and doesn't have newlines. You need to use binary I/O calls.
the data is buffered. You need to either flush the stdout of the middle process process_stuff_out_data if you can rewrite it, or just wait until abc and process_stuff_out_data exit.
process_stuff_out_data is writing to stderr, not stdout. Or it is writing to the console (ugh), i.e. /dev/console.

popen error redirection unexpected when running grep using /bin/bash in ubuntu

I'm trying to work through a simple hackerank problem and I'm stuck.
When executing grep on the command line, I have no issues
grep -i \"the[^a-z0-9]\" $filename <<< "from fairest creatures we desire increase"
result: (returns nothing)
grep -i \"the[^a-z0-9]\" $filename <<< "the clock struck twice"
result: the(highlighted) clock struck twice
I read this article :
Can I open bash from a popen() stream?
I have tried prepending the grep command with "exec bash -c" and "/bin/bash -c" to no avail.
Can anyone tell me why I'm getting this error and how to fix it?
sh: 1: Syntax error: redirection unexpected
f is null
My code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include<cmath>
using namespace std;
int main(){
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int MAX_BUFFER =2048;
string output;
char fileInput [MAX_BUFFER];
// string input(istreambuf_iterator<char>(cin), {});
string input =" From fairest creatures we desire increase ,\
That thereby beauty's rose might never die,\
But as the riper should by time decease,\
His tender heir might bear his memory:\
But thou contracted to thine own bright eyes,\
Feed'st thy light's flame with self-substantial fuel,\
Making a famine where abundance lies,\
Thy self thy foe, to thy sweet self too cruel:\
Thou that art now the world's fresh ornament,\
And only herald to the gaudy spring,\
Within thine own bud buriest thy content,\
And tender churl mak'st waste in niggarding:\
Pity the world, or else this glutton be,\
To eat the world's due, by the grave and thee.\
When forty winters shall besiege thy brow,\
And dig deep trenches in thy beauty's field,\
Thy youth's proud livery so gazed on now,\
Will be a tattered weed of small worth held:\
Then being asked, where all thy beauty lies,\
Where all the treasure of thy lusty days;\
To say within thine own deep sunken eyes,\
Were an all-eating shame, and thriftless praise.\
How much more praise deserved thy beauty's use,\
If thou couldst answer 'This fair child of mine\
Shall sum my count, and make my old excuse";
string cmd_string = "/bin/bash -c grep -i \"the[^a-z0-9]\" $filename <<< "+input;
//cout<<cmd_string.c_str();
FILE *f=popen(cmd_string.c_str(),"r");
while (!feof(f))
{
if (fgets(fileInput, MAX_BUFFER, f) != NULL)
{
cout<<" line 1"<<fileInput[0];
output+=fileInput;
}
else
{
cout<<"f is null"<<endl;
}
}
pclose(f);
cout<< output;
return 0;
}
The normal (and almost universal) convention for handling command-line flags which take arguments is that the single argument following the command-line flag itself is the associated argument. Subsequent arguments are either other flags or positional arguments.
That's certainly true of bash. If you want to use the -c command-line flag to execute a bash command, the entire command needs to be the argument to the -c flag, and it needs to be a single argument. Subsequent arguments are assigned to $0, $1, etc. before the command is executed.
So if you type:
bash -c echo foo
you will see a blank line. You could do this:
bash -c 'echo $0' foo
which will print foo "as expected" (if your expectations are well-honed), but it would be normal to do this:
bash -c 'echo foo'
Similarly, if you execute
/bin/bash -c grep -i \"the[^a-z0-9]\" ...
you are asking bash to execute the command grep with no arguments; the -i and subsequent arguments are assigned to $0, etc., but since those are never referenced by the command, that is somewhat pointless.
What you meant was
/bin/bash -c 'grep -i "the[^a-z0-9]" ... '
(You cannot backslash escape anything inside single-quoted strings, so the backslashes are removed. I don't see how they could have worked in the original command-line either; there are no double quotes to match in the target string.)
Obviously, it is vital that the here-string (<<<"...poem...") be part of the -c argument to /bin/bash and not part of the command-line interpreted by popen. popen uses sh to execute the provided command-line, and it is highly likely that sh does not recognize the "here-string" syntax; it's a bash extension. Because <<< is not special in sh, << is interpreted normally as a here-doc, which must be followed by a delimiter string. It cannot be followed by a < redirection; hence the "unexpected redirection" error. When you make the word following <<< very long, you apparently trigger a "filename too long" error before the erroneous redirection has been parsed. That's just a guess; I didn't reproduce the problem.
Quoting is going to be annoying for you. As mentioned, there is no problem with " inside single-quoted strings, but you will have to backslash the double-quotes to comply with C string literal syntax. Unfortunately, the string literal contains single quotes, and the first of those will be parsed as closing the single-quote in bash -c '. And there is no way to backslash-escape anything inside bash single-quoted strings, not even a single quote.
The only thing that will work will be to represent each ' with the sequence '\'' (which will need to be '\\'' inside the C string). In that sequence, the first and last ' close and reopen the single-quoted string, and the \' in the middle is a backslash-escaped '.
Three final notes:
$filename has no effect in your commands, since $filename has never been defined. If it were defined, it would create a variety of errors; since it is not defined and the expansion is not quoted, it simply disappears from the command-line, but it would be a lot easier not to put it there in the first place.
C strings can be continued from line to line using a backslashed newline, as in your sample code, but that does not insert a newline into the string. So the input provided to grep will be a single line. I don't think that's what you meant.
You do have to quote the here-string; the syntax of here-strings is <<< followed by a single "word"; if you don't put quotes around it, you'll end up with only the part up to the first space being treated as input.
I think your input is not quoted.
string cmd_string = "/bin/bash -c grep -i \"the[^a-z0-9]\" $filename <<< "+ \" + input + \";

Examining a word in gdb prints in decimal instead of hex

I am trying to examine some addresses in gdb. It was printing in hex previously but I'm not sure how I changed it. When I enter x/20 $rsp the result looks like this:
0x7fffffffb060: -20336 32767 -559038737 0
Obviously this is not the end of the world since I can manually convert the values if needed but it is pretty annoying. I've tried exiting gdb and restarting but that does nothing.
gdb uses the last specified setting when printing values. To force hexadecimal, append x: x/20x addr.
faced the same issue, I try to print one byte first and then x/x shows hex values
or
use x/4bx to display 4 bytes in hex, there is an extra x in the end.

converting binary to text in linux

I have a big binary file I have produced by writing an array of float numbers in binary format.
Now how can I simply convert that binary file to text ?
Use the UNIX od command, with the -t f4 option to read the file as 4 byte floating point values. The -A n option is also useful to avoid printing the file offsets. Here is the output of an example file that I created.
/tmp> od -A n -t f4 b.dump
-999.876 -998.876 -997.876 -996.876
-995.876 -994.876 -993.876 -992.876
-991.876 -990.876 -989.876 -988.876
-987.876 -986.876 -985.876 -984.876
You will need to reverse the process.
Read the file back into an array of floats.
Print the array use printf() or your favorite io function.
Any other approach will be ugly and painful; not to say this isn't ugly to start with.