Console system() output into a int variable - c++

I'm trying to read the resolution of my screen by using the following system() function.
system("system_profiler SPDisplaysDataType | grep Resolution | uniq | awk '{print $2}' | cut -d 'x' -f2");
Unfortunatly I can not use popen I'm working on Xcode and the program collapses with popen, so it has to be system(). But, the problem is that I don't know how to collect the data this system call is sending to the console into a int variable. I tried;
w << std::cerr << std::endl;
const std::string W(w.str());
int j = atoi(W.c_str());
cerr << "VALUE 2: " << j;
That's supposted to convert the cerr exit that system is giving into a a string, then a char and then finally a int :) but doesn't work.
Any idea? Thank you in advance.

Related

how to turn program into deamon program

I sometimes write program like this to process offline data:
load_model() //this may cost lots of time
while(cin >> inputs)
{
result = process_input(inputs)
cout << result
}
release_model()
This works fine if I only have to process offline data. However, when the data comes one by one I am in trouble. Since I have to load the model everytime which is time consuming.
I wonder if there is any way to CONVERT this program into a service WITHOUT modify the program itself. For example, I can redirect the cin and cout to two named pipes:
program < namedpipe_in > namedpipe_out
The I can put the inputs into the namedpipe_in like this
cat input > namedpipe_in
and read the result in another pipe:
cat namedpipe_out
However, this solution will not work since once I cat something to the namedpipe_in, the pipe will be close after cat operation and the program exits.
My question is how to fix this problem and make the pipes looks more like a queue instead of a memory buffer.
Thanks for your time reading.
Perhaps I am misunderstanding your question; please correct me if this is not what you are looking for.
To simulate your example, I wrote a simple C++ program which just takes in each input string and reverses it:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::cout << ":start:" << std::endl;
std::string str;
while(std::cin >> str)
{
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
}
}
The output binary of my example program is strflipper.
I have another file called in.log which is just an input file which I created via touch in.log.
Now I call
tail -f in.log | ./strflipper > out.log
and if I add something to the input log in a different terminal, the output log gets adjusted as such:
$ echo "abc" >> in.log
$ echo "foo" >> in.log
$ echo "bar baz" >> in.log
$ cat out.log
:start:
cba
oof
rab
zab
which of course is my expected output. As long as I don't kill the program, anything I add into in.log will automatically be processed within that loop without killing or restarting strflipper.

synchronous write of redirected stdout and std::ofstream to a file under unix c++

This is a buildup on an earlier question of mine: redirect stdout to a file
The situation is as follows: I am using an external library which provides vital functionality to my code, but which produces a large amount of logging information via printf (bad style, I know, but I can't change it, and I can't switch to another library).
I would like to redirect the output to a file, which I have managed to achieve with the help of the great StackOverflow community (see earlier link). Since then, the situation has gotten a little more complicated: Now I want to append my own logging information to the same output file, preferably using std::ofstream. The code is not and will never be parallelized, so concurrent write access is not a concern. However, please consider the following chunk of code:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// this is just a global "backup" of the stdout fd
// so that I can restore it after the function call
int stdoutfd = dup(fileno(stdout));
int stupid_library_function(){
// I can't change this function
printf("hello world!\n");
return 1;
}
int redirect_stdout(const char* fname, bool append){
// redirect printf to a file
fflush(stdout);
int newstdout = append ? open(fname, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) : open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
dup2(newstdout, fileno(stdout));
close(newstdout);
return fileno(stdout);
}
int restore_stdout(){
// restore the normal behaviour of printf
fflush(stdout);
dup2(stdoutfd, fileno(stdout));
return stdoutfd;
}
int main(){
// just to test if everything is normal
std::cout << "this is a normal printout" << std::endl;
// create my own output stream
std::ofstream outstream("log.txt");
// some of my own output
outstream << "calling stupid library function now" << "\n";
outstream.flush();
// redirect the output of the supid library function to the logfile
redirect_stdout("log.txt",true);
int val = stupid_library_function();
// neither of the following lines causes the output of the stupid library function to appear in the log file
fflush(stdout);
fsync(stdoutfd);
// restore the normal stdout
restore_stdout();
// some of my own output again
outstream << "done calling stupid library function, result was " << val << "\n";
outstream.flush();
// close my own output stream
outstream.close();
// just to test if everything is back to normal
std::cout << "this is (again) a normal printout" << std::endl;
return 1;
}
Compiling and running this code should give you a file "log.txt", which would contain the following lines
calling stupid library function now
done calling stupid library function, result was 1
Due to my naive understanding, the file should contain three lines, the output "hello world" from the library function call between the two you find above.
My first thought were that there was a problem with flushing the stdout buffer, so I tried using "fflush" and "fsync" (see above). However, neither of those seem to have any effect in this case.
Would anybody be willing to enlighten me and show me a way of how to obtain the output
calling stupid library function now
hello world
done calling stupid library function, result was 1
with the following constraints:
the lines in the log file must be in the correct order
printf and std::cout must be restored to default behaviour when the code is done
the code of "stupid_library_function" must not be changed
the output within "main" must still be using std::ofstream

Piping input to an already running cpp program?

include
Lets assume that this is the code I am running:
int main(int argc, char **argv) {
bool running = true;
string lineInput;
while (running)
{
while (cin >> lineInput)
{
cout << lineInput;
}
}
return 0;
}
What I would like to have happen is that I can call start a program from terminal by typing "./myProgram" That part is fairly straight forward. The part I'm not sure how to do is make it so that I can at a later point in time type echo "some text to echo" | myProgram and be able to have my program then print that text back out to the terminal.
Right now I can only make it work if I type:
echo "blah blah blah" | ./myProgram
So my goal is to have two separate steps. One where I start my program, and a second when I pipe it some input to use
I'm thinking you could do this with a named pipe.
mkfifo mypipe
./myProgram < mypipe &
cat file1.txt file2.txt file3.txt > mypipe
You can use mkfifo, and just read from that in the program as from an ordinary file.
There's also
pipe or socket_pair (bi-directional)

c++ linux system command

I have the following problem:
I use in my program this function:
system("echo -n 60 > /file.txt");
it works fine.
But I don't want to have constant value. I do so:
curr_val=60;
char curr_val_str[4];
sprintf(curr_val_str,"%d",curr_val);
system("echo -n curr_val_str > /file.txt");
I check my string:
printf("\n%s\n",curr_val_str);
Yes,it is right.
but system in this case doesn't work and doesn't return -1. I just print string!
How can I transfer variable like integer that will be printed in file like integer, but don't string?
So I want to have variable int a and I want to print value of a with system function in file. A real path to my file.txt is /proc/acpi/video/NVID/LCD/brightness. I can't write with fprintf. I don't know why.
you cannot concatenate strings like you are trying to do. Try this:
curr_val=60;
char command[256];
snprintf(command, 256, "echo -n %d > /file.txt", curr_val);
system(command);
The system function takes a string. In your case it's using the text *curr_val_str* rather than the contents of that variable. Rather than using sprintf to just generate the number, use it to generate the entire system command that you require, i.e.
sprintf(command, "echo -n %d > /file.txt", curr_val);
first ensuring that command is large enough.
The command that is actually (erroneously) executed in your case is:
"echo -n curr_val_str > /file.txt"
Instead, you should do:
char full_command[256];
sprintf(full_command,"echo -n %d > /file.txt",curr_val);
system(full_command);
#define MAX_CALL_SIZE 256
char system_call[MAX_CALL_SIZE];
snprintf( system_call, MAX_CALL_SIZE, "echo -n %d > /file.txt", curr_val );
system( system_call );
man snprintf
The correct way would be similar to this:
curr_val=60;
char curr_val_str[256];
sprintf(curr_val_str,"echo -n %d> /file.txt",curr_val);
system(curr_val_str);
Just DON'T. :)
Why resort to system() for such a simple operation?
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int write_n(int n, char * fname) {
char n_str[16];
sprintf(n_str, "%d", n);
int fd;
fd = open(fname, O_RDWR | O_CREAT);
if (-1 == fd)
return -1; //perror(), etc etc
write(fd, n_str, strlen(n_str)); // pls check return value and do err checking
close(fd);
}
Have you considered using C++'s iostreams facility instead of shelling out to echo? For example (not compiled):
std::ostream str("/file.txt");
str << curr_val << std::flush;
Alternately, the command you pass to system must be fully formatted. Something like this:
curr_val=60;
std::ostringstream curr_val_str;
curr_val_str << "echo -n " << curr_val << " /file.txt";
system(curr_val_str.str().c_str());
Use snprintf to avoid security issues.
What about using std::string & std::to_string...
std::string cmd("echo -n " + std::to_string(curr_val) + " > /file.txt");
std::system(cmd.data());

Why does my output go to cout rather than to file?

I am doing some scientific work on a system with a queue. The cout gets output to a log file with name specified with command line options when submitting to the queue. However, I also want a separate output to a file, which I implement like this:
ofstream vout("potential.txt"); ...
vout<<printf("%.3f %.5f\n",Rf*BohrToA,eval(0)*hatocm);
However it gets mixed in with the output going to cout and I only get some cryptic repeating numbers in my potential.txt. Is this a buffer problem? Other instances of outputting to other files work... maybe I should move this one away from an area that is cout heavy?
You are sending the value returned by printf in vout, not the string.
You should simply do:
vout << Rf*BohrToA << " " << eval(0)*hatocm << "\n";
You are getting your C and C++ mixed together.
printf is a function from the c library which prints a formatted string to standard output. ofstream and its << operator are how you print to a file in C++ style.
You have two options here, you can either print it out the C way or the C++ way.
C style:
FILE* vout = fopen("potential.txt", "w");
fprintf(vout, "%.3f %.5f\n",Rf*BohrToA,eval(0)*hatocm);
C++ style:
#include <iomanip>
//...
ofstream vout("potential.txt");
vout << fixed << setprecision(3) << (Rf*BohrToA) << " ";
vout << setprecision(5) << (eval(0)*hatocm) << endl;
If this is on a *nix system, you can simply write your program to send its output to stdout and then use a pipe and the tee command to direct the output to one or more files as well. e.g.
$ command parameters | tee outfile
will cause the output of command to be written to outfile as well as the console.
You can also do this on Windows if you have the appropriate tools installed (such as GnuWin32).