C++ FLTK displaying a sysctl value

I am trying to display a sysctl value in an FLTK Fl_Output box.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Output.H>

void box1cb(Fl_Widget *, void *) {
system("sysctl -n dev.cpu.0.temperature");
}

int main(int argc, char ** argv) {
  Fl_Window *window = new Fl_Window(400,200, "CPU Temperature");

  Fl_Output *box1 = new Fl_Output(180, 90, 70, 30, "CPU0");
  box1->callback(box1cb,0);
  box1->labelsize(20);

  window->end();
  window->show(argc,argv);
  return Fl::run();
}

What is the special sauce I need to display the sysctl value in the Fl_Output box? When I hit return in the box I get the value but returned in the calling command prompt not in GUI.
I tried 'fprint' statement in several spots and I can't figure this out.
Please help me.
I am not sure if I am missing something in the callback. With my previous usage the callback event was initiated by 'button pressing'.
On this learning adventure I just want to see the sysctl value on startup. No polling or redraw needed for now.
I have been through all the examples and I cannot figure it out.
 
I was thinking maybe my box is of wrong type. I saw Fl_Value_Output and wondered if I am using the correct output type.

So I changed type to Fl_Value_Output. It seems to behave differently but does not work. Not feedback in console at all.

For such a simple example I do not think I would even need a callback. Am I wrong?
 
No , you are not wrong but je need popen.


Code:
#include <stdlib.h>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Output.H>
#include <string.h>
#define MAX_BUFFER_SIZE 100
#define COMMAND "sysctl -n dev.cpu.0.temperature"
int main(int argc, char ** argv)
{
Fl_Window *window = new Fl_Window(400,200, "CPU Temperature");
Fl_Output *box1 = new Fl_Output(180, 90, 70, 30, "");
FILE *fp;
char result_buffer[MAX_BUFFER_SIZE];
memset(result_buffer, 0, MAX_BUFFER_SIZE);
fp = popen(COMMAND, "r");
    if (fp == NULL) {
        printf("Failed to run command\n");
        exit(1);
    }
if (fgets(result_buffer, sizeof(result_buffer), fp) != NULL) {
        printf("System Command Output Stored in String: %s \n", result_buffer);
    } else {
        printf("No output was captured from the command.\n");
    }
 pclose(fp);
result_buffer[sizeof(result_buffer)-4]=0;
box1->value(result_buffer); // THE BOX HAS NOW AS TEXT THE RESULT OF THE SYSCTL COMMAND
box1->labelsize(20);
window->end();
window->show(argc,argv);
return Fl::run();
}

g++ test.cpp -lfltk ; ./a.out
 
What does FILE *fp do?

Compile troubles for me:
Code:
utput.cxx:29:1: error: use of undeclared identifier 'my_output_box'
   29 | my_output_box->value(resultbuffer) # THE BOX HAS NOW AS TEXT THE RESULT OF THE SYSCTL COMMAND
      | ^
output.cxx:29:22: error: use of undeclared identifier 'resultbuffer'; did you mean 'result_buffer'?
   29 | my_output_box->value(resultbuffer) # THE BOX HAS NOW AS TEXT THE RESULT OF THE SYSCTL COMMAND
      |                      ^~~~~~~~~~~~
      |                      result_buffer
output.cxx:15:6: note: 'result_buffer' declared here
   15 | char result_buffer[MAX_BUFFER_SIZE];
      |      ^
2 errors generated.
 
Working popen program ,without ugly control character

Code:
#include <stdlib.h>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Output.H>
#include <string.h>
#include <algorithm>
#define MAX_BUFFER_SIZE 100
#define COMMAND "sysctl -n dev.cpu.0.temperature"
#include <stdio.h>
void print_hex(const char *s) {
    printf("[");
    // Loop through the string until the null terminator ('\\0') is reached
    while (*s) {
        // Cast the character to an unsigned int for safe promotion and use the %02x format specifier.
        // %02x prints the value as a two-digit hexadecimal number, using a leading zero for padding if necessary.
        printf("(%02x)", (unsigned int)(unsigned char)*s++);
    }
    printf("]");
    printf("\n"); // Print a newline at the end
}
void remove_char(char* str, char char_to_remove) {
    char *read_ptr = str; // Pointer to read from the original string
    char *write_ptr = str; // Pointer to write to the modified string
    while (*read_ptr) {
        // If the character at the read pointer is NOT the one to remove, 
        // copy it to the location of the write pointer and advance both pointers.
        if (*read_ptr != char_to_remove) {
            *write_ptr++ = *read_ptr++;
        } else {
            // If the character is the one to remove, only advance the read pointer, 
            // effectively skipping it. The write pointer stays in place until a 
            // valid character is found.
            read_ptr++;
        }
    }
    // Null-terminate the resulting string at the position of the write pointer
    *write_ptr = '\0';
}
int main(int argc, char ** argv) 
{
Fl_Window *window = new Fl_Window(400,200, "CPU Temperature");
Fl_Output *box1 = new Fl_Output(180, 90, 70, 30, "");
FILE *fp;
char result_buffer[MAX_BUFFER_SIZE];
memset(result_buffer, 0, MAX_BUFFER_SIZE);
fp = popen(COMMAND, "r");
    if (fp == NULL) {
        printf("Failed to run command\n");
        exit(1);
    }
if (fgets(result_buffer, sizeof(result_buffer), fp) != NULL) {
        printf("System Command Output Stored in String: %s \n", result_buffer);
    } else {
        printf("No output was captured from the command.\n");
    }
 pclose(fp);
result_buffer[sizeof(result_buffer)-1]='\0';
// To represent the actual control character in the code, use its ASCII value:
print_hex(result_buffer);

char char_to_remove = (char)0x0a;
printf("Original string: [%s] \n", result_buffer);
remove_char(result_buffer, char_to_remove);
printf("Filtered string: [%s] \n", result_buffer);
box1->value(result_buffer); // THE BOX HAS NOW AS TEXT THE RESULT OF THE SYSCTL COMMAND
box1->labelsize(20);
window->end();
window->show(argc,argv);
return Fl::run();
}
 
Thanks
In addition to popen I see that box1 "value->" is the key firing part I was missing. I will study that.

I am looking at sysctlbyname examples now.
 
Last and final "popen" program,

Code:
#include <stdlib.h>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Output.H>
#include <string.h>
#include <algorithm>
#define MAX_BUFFER_SIZE 100
#define COMMAND "sysctl -n dev.cpu.0.temperature"
#include <stdio.h>

size_t custom_strlen(const char* str, size_t max_len) {
    size_t length = 0;
    // Iterate through the array bounds
    while (length < max_len && str[length] != '\0') {
        length++;
    }
    return length;
}

int main(int argc, char ** argv) 
{
Fl_Window *window = new Fl_Window(400,200, "CPU Temperature");
Fl_Output *box1 = new Fl_Output(180, 90, 70, 30, "");
FILE *fp;
char result_buffer[MAX_BUFFER_SIZE];
memset(result_buffer, 0, MAX_BUFFER_SIZE);
fp = popen(COMMAND, "r");
    if (fp == NULL) {
        printf("Failed to run command\n");
        exit(1);
    }
if (fgets(result_buffer, sizeof(result_buffer), fp) != NULL) {
        printf("System Command Output Stored in String: %s \n", result_buffer);
    } else {
        printf("No output was captured from the command.\n");
    }
 pclose(fp);
printf("Original string: [%s] \n", result_buffer);
size_t len1 = custom_strlen(result_buffer, MAX_BUFFER_SIZE);
result_buffer[len1-1]=' '; // REMOVE UGLY CHARACTER
printf("Filtered string: [%s] \n", result_buffer);
box1->value(result_buffer); // THE BOX HAS NOW AS TEXT THE RESULT OF THE SYSCTL COMMAND
box1->labelsize(20);
window->end();
window->show(argc,argv);
return Fl::run();
}
 
Fyi, i use conky to show information about my system, but fltk was fun,
 
I prefer F# language when i can but currently learning C++.
Gone write for fun a C++ - Fltk system monitor program.
With a calender using , Fl_Multiline_Output.
When i finished watching the udemy course on Qt6 I'll migrate it to C++ - Qt6.
 
I built an example with Fl_Multiline_Output that really inspired me.
It was only PING in a window but I knew at that point what I wanted was feasible.

I look forward to learning gauges. FLTK's are limited but capable...

Could I build a R/C Vehicle/boat/robot onscreen display and control with FLTK/C++... That is something I am interested in.
There are some amazing drone computers these days like PixHawk ect. ect. and I have a soft spot for that type gear.

I really want to Thank Alain De Vos for the assistance. I am the person who need needs to study what was provided.
After tweaking the work for my taste I might dive into sysctlbyname.

I was thinking I will donate and EXTRA $100 to the foundation just for helping when I mail my check soon.

Maybe another EXTRA $200 to the foundation for helping me if I get libGPIO API working with FLTK.
 
The Amazon DeepRacer vehicle has an Intel E3930 CPU embedded. I like the whole concept here but "Amazon" and "Cloud" are not things I want for my learning project.

Make a FreeBSD FLTK ControlPanel for this guy? Point to point with collision avoidance.
 
Back
Top