Terminalbreite mit getenv() auswerten
-
Hallo *,
ich würde gerne die Shellfensterbreite auswerten um einen Fortschrittsbalken zu erzeugen.
Derzeit versuche ich das so:void progress( float factor ) { int MAX_CHARS = 70; char* string_ptr = getenv( "COLUMNS" ); if( string_ptr != NULL ) { //cout << "COL: " << string_ptr << endl; MAX_CHARS = atoi( string_ptr ) - 10; if( MAX_CHARS < 0 ) MAX_CHARS = 0; } cout << setw( static_cast<int>( factor * MAX_CHARS ) ) << setfill( '#' ) << ""; cout << setw( MAX_CHARS - static_cast<int>( factor * MAX_CHARS ) ) << setfill( '·' ) << ""; cout << " " << setw( 6 ) << setfill( ' ' ) << setprecision( 2 ) << fixed << right << static_cast<float>( factor * 100 ) << "%"; cout << flush; cout << "\r"; }
Leider ist "string_ptr" immer NULL. Wie kommt das?
Viele Grüße
Bastian
-
was sagt denn echo $COLUMNS?
Ist die Variable überhaupt gesetzt?
-
Die Variable COLUMNS ist nicht definiert. Ich hab grad mal bei google geguckt, anscheinend ist es Usus, als Breite 80 anzunehmen, wenn COLUMNS nicht existiert.
-
Ich habe mal ein bisschen recherchiert und habe folgendes herausgefunden:
COLUMNS wird standardmäßig nicht exported, da sich während des Programmlaufs die Größe des Terminals ändern kann. Die Änderungen im Environment aber nicht mehr vom Parent (der Shell, also dem Programm was diese Variable erst einmal setzt) vorgenommen werden können.
Während des Programmlaufs kann man die Fenstergröße jedoch mit ioctls(), TIOCGWINSZ und struct winsize herausfinden.Danach habe ich die Funktion jetzt folgendermaßen implementiert:
void progress( float factor ) { static struct winsize winsz; static int MAX_CHARS = 72; if( 0 == ioctl( 0, TIOCGWINSZ, &winsz ) ) { MAX_CHARS = winsz.ws_col; if( MAX_CHARS > 8 ) MAX_CHARS -= 8; } cout << setw( static_cast<int>( factor * MAX_CHARS ) ) << setfill( '#' ) << ""; cout << setw( MAX_CHARS - static_cast<int>( factor * MAX_CHARS ) ) << setfill( '·' ) << ""; cout << " " << setw( 6 ) << setfill( ' ' ) << setprecision( 2 ) << fixed << right << static_cast<float>( factor * 100 ) << "%"; cout << flush; cout << "\r"; }
Viele Grüße
Bastian