0

Sorry if this is a very noob question, but i'm just starting with ncurses (and C++).

I'm trying to call a system command inside a ncurses code (for the example, anything will work) and to store the output in a variable, not displaying it until i print it, but when i create a variable with the system() output, it is printed automatically in the screen.

This is my code so far:

#include <iostream>
#include <string>
#include <ncurses.h>

using namespace std;

string g;

int main()
{

initscr();
int h, w;
getmaxyx(stdscr, h, w);   
cbreak();
refresh();

g=system("date");

WINDOW* w1_b = newwin(h, w/2, 0, 0);
box(w1_b, 0 , 0);
WINDOW* w2_b = newwin(h/2, w/2, 0, w/2);
box(w2_b, 0 , 0);
WINDOW* w3_b = newwin(h/2, w/2, h/2, w/2);
box(w3_b, 0 , 0);

wrefresh(w1_b);
wrefresh(w2_b);
wrefresh(w3_b);

WINDOW* w1 = newwin(h-2, (w/2)-2, 1, 1);
WINDOW* w2 = newwin((h/2)-2, (w/2)-2, 1, (w/2)+1);
WINDOW* w3 = newwin((h/2)-2, (w/2)-2, (h/2)+1, (w/2)+1);

mvwprintw(w1, 1, 1, "Window 1");
mvwprintw(w2, 1, 1, "Window 2");
mvwprintw(w3, 1, 1, "Window 3");

wrefresh(w1);
wrefresh(w2);
wrefresh(w3);

getch();

endwin(); 
return 0;       

}

Now, when g=system("date"); is executed, the date is automatically printed in the screen, even if i'm storing it inside a variable (g in this case), Any idea of what can be wrong?

Ghost
  • 1,426
  • 5
  • 19
  • 38
  • Probably a dupe: [How to execute a command and get output of command within C++ using POSIX?](http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c-using-posix) – user4581301 Jan 26 '17 at 22:47
  • Possible duplicate of [How to execute a command and get output of command within C++ using POSIX?](http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c-using-posix) – Thomas Dickey Jan 27 '17 at 00:57

3 Answers3

2

The popen() function can be used to execute a command and to read its output programatically.

G. Sliepen
  • 7,637
  • 1
  • 15
  • 31
1

You are not storing in a variable. The std::system() function returns the exit value of the command you executed, not the text which (if any) the command would write to standard output. Use of std::system() is inappropriate in any serious C or C++ code - personally I would like to see it deprecated in both languages.

  • 1
    It's nice to see you back, Neil. But re "Use of std::system() is inappropriate in any serious C or C++ code", while that does depend on the definition of "serious", like Bill Clinton's defense that the truth or not of his statement depended on the definition of the word "is", it's generally just an unfounded ungood meme. It's expressed in many answers here on SO, but it's just bollocks. `system` provides a valuable, even if slightly limited, service. – Cheers and hth. - Alf Jan 26 '17 at 22:51
  • *Use of std::system() is inappropriate in any serious C or C++ code* Nonsense. Bollocks. There are numerous valid reasons to use `system()`: use of a third-party utility unavailable otherwise and easy separation of a child process are but two. – Andrew Henle Jan 26 '17 at 22:52
  • @Alf I don't see how it can be valuable. You can't capture the output of the command, it freezes your application until it completes (if it does), it emits no diagnostic error messages other than the return value, etc, etc. I have _never_ used it in any program I have written, and I cannot imagine how well-written code could use it. But perhaps you could post an example of some that does. –  Jan 26 '17 at 22:55
  • @NeilButterworth Why do you assume *all* use cases *require* **directly** capturing the output and/or diagnostic messages of the child process, along with execution parallel to the *single* thread that calls `system()`? – Andrew Henle Jan 26 '17 at 22:58
  • @Andrew I don't assume it, that's what every program I have ever written needs to do when executing another process. –  Jan 26 '17 at 23:00
  • @NeilButterworth *I don't assume it, that's what every program I have ever written needs to do when executing another process.* So your experience is a limit on what every other person writing code needs to do? – Andrew Henle Jan 26 '17 at 23:01
  • @Andrew If you have good example of how to use std::system(), then post a link to it. –  Jan 26 '17 at 23:02
  • 1
    @NeilButterworth: Well, minimal examples are easy. In Windows you can use `system` to switch the console window to the right codepage, and clear it, without dealing with the Windows API's console functions, like `system( "chcp 1252 & cls" )`. That's a very tiny little bit of functionality, but it's handy. Or you could access `wmic` output. – Cheers and hth. - Alf Jan 26 '17 at 23:07
  • @NeilButterworth *If you have good example of how to use std::system(), then post a link to it.* Why do **I** have to provide any link? **You** are the one claiming your experience is sufficient proof that *[u]se of `std::system()` is inappropriate*. That's arrogant. Along with downright risible. **You** have the burden to support your claim. – Andrew Henle Jan 26 '17 at 23:08
  • @Andrew How is claiming that the use of _any_ function is inappropriate "arrogant"? For example do you think there is any defensible use of atoi()? Do you think that saying "never use that function" is in some way "arrogant"? –  Jan 26 '17 at 23:09
1

First, note that the commands you use with system, and their effects and output, are necessarily system dependent. To obtain the current date you're far better off using the relevant standard library functions for that. Or calendar functionality from Boost (unfortunately there are too many calendar sub libraries in Boost, at least two, but just pick one).

system returns the command's process exit code. In order to obtain the command's output, if any, you can redirect it to a file, which you can then subsequently open and read. This is trivial to do with the Unix-land and Windows command processors, ¹just >myfile.txt in the command.

Alternatively you can set up a pipe and poll it. That's not supported by the C++ standard library, and you don't use system to do this. It avoids the file, and it lets your program deal with output from a continuously running process, but there is a cost in complexity and system dependencies.

Again, using system to obtain the current date is inappropriate.

Use the relevant direct standard library functionality, only use system or other means where the standard library doesn't provide what you need.


¹ The tmpnam function & family can be useful.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331