Discussion:
Stringvorgabe für scanf ?
(zu alt für eine Antwort)
wolfgang bauer (D)
2022-05-07 10:23:34 UTC
Permalink
Hallo

Ich möchte eine Eingabe für scanf vorgeben, so das man in der Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss.

puts/putchar schreiben offenbar nicht in den Buffer für scanf.
--
Gruß, Greetings
Helmut Schellong
2022-05-07 13:21:53 UTC
Permalink
Post by wolfgang bauer (D)
Hallo
Ich möchte eine Eingabe für scanf vorgeben, so das man in der Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss.
puts/putchar schreiben offenbar nicht in den Buffer für scanf.
Lies die Beschreibung von scanf gründlich durch.
Man kann da ja diverse Flags und Längen angeben
und mit einer Zeichenklasse (!) arbeiten.

Müßte man nicht per "%s" einen Leerstring eingeben können?
Daß also nur str[0]='\0' gemacht wird.
Ich selbst verwende sehr selten scanf, sondern open,read,write,etc.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
Stefan Ram
2022-05-07 14:12:57 UTC
Permalink
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken
muss.
Ich denke nicht, daß dies mit Standard-C geht.

Vielleicht geht es mit speziellen Konsolen-Funktionen,
aber dann wäre es nicht portabel. (Frage zum Beispiel
in einer Windows-Newsgroup danach.)

Was vielleicht geht, wäre es, bei einer "leeren" Eingabe
eine Vorgabe zu verwenden.

Aber selbst das würde nicht mit "scanf" gehen. Man müßte
"getchar" verwenden. Aber dann müßte man viele Fähigkeiten
von "scanf" aufwendig manuell implementieren. Eine Demo:

main.c

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 4096
#define xstr(a) str(a)
#define str(a) #a

int main( void )
{ char input[ BUFFER_SIZE ];
printf( "Zahl (Eingabetaste fuer 0)? " );
char * p = input;
const char * const top = input + BUFFER_SIZE;
char ch = '\0';
while( p < top && ch != '\n' )*p++ = ch =( char )getchar();
if( p < top )*p++ = '\0';
if( *input == '\n' )
{ puts( "Eingabetaste erkannt." );
strcpy( input, "0\n" ); }
printf( "Eingabe = %." xstr( BUFFER_SIZE ) "s\n", input ); }
Helmut Schellong
2022-05-07 17:49:10 UTC
Permalink
Post by Stefan Ram
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken
muss.
Ich denke nicht, daß dies mit Standard-C geht.
Vielleicht geht es mit speziellen Konsolen-Funktionen,
aber dann wäre es nicht portabel. (Frage zum Beispiel
in einer Windows-Newsgroup danach.)
Was vielleicht geht, wäre es, bei einer "leeren" Eingabe
eine Vorgabe zu verwenden.
Aber selbst das würde nicht mit "scanf" gehen. Man müßte
"getchar" verwenden. Aber dann müßte man viele Fähigkeiten
|All conversions are introduced by the % (percent sign) character.
|The format string may also contain other characters.
|White space (such as blanks, tabs, or newlines) in the format string
|match any amount of white space, including none, in the input.

Wie ich bereits schrieb.
Es kann sich lohnen, die Beschreibung zu lesen und ein paar Versuche zu machen.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
Thomas Noll
2022-05-07 18:26:26 UTC
Permalink
Post by Helmut Schellong
Post by Stefan Ram
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken
muss.
Ich denke nicht, daß dies mit Standard-C geht.
Vielleicht geht es mit speziellen Konsolen-Funktionen,
aber dann wäre es nicht portabel. (Frage zum Beispiel
in einer Windows-Newsgroup danach.)
Was vielleicht geht, wäre es, bei einer "leeren" Eingabe
eine Vorgabe zu verwenden.
Aber selbst das würde nicht mit "scanf" gehen. Man müßte
"getchar" verwenden. Aber dann müßte man viele Fähigkeiten
|All conversions are introduced by the % (percent sign) character.
|The format string may also contain other characters.
|White space (such as blanks, tabs, or newlines) in the format string
|match any amount of white space, including none, in the input.
Wie ich bereits schrieb.
Es kann sich lohnen, die Beschreibung zu lesen und ein paar Versuche zu machen.
Das ist aber auch trivial, mit scanf etwas einzulesen und bei speziellen
Eingaben eineSonderbehandlung zu machen. Gefragt war aber wohl eher ein
Verhalten wie z.B die bash mit readline support mit read -i bietet.

Und das kann man, erstaunlicherweise, mit der readline lib bekommen.
Ausgangspunkt int rl_insert_text (const char *text), wie es genau geht,
wird der OP uns dann sicher wissen lassen, wenn er es umgesetzt hat.
--
Dummheit und Gewissheit sind siamesische Zwillinge.
Ganz sicher!
wolfgang bauer (D)
2022-05-07 18:41:42 UTC
Permalink
Post by Thomas Noll
Das ist aber auch trivial, mit scanf etwas einzulesen und bei speziellen
Eingaben eineSonderbehandlung zu machen. Gefragt war aber wohl eher ein
Verhalten wie z.B die bash mit readline support mit read -i bietet.
Und das kann man, erstaunlicherweise, mit der readline lib bekommen.
Ausgangspunkt int rl_insert_text (const char *text), wie es genau geht,
wird der OP uns dann sicher wissen lassen, wenn er es umgesetzt hat.
Erstmal Danke an alle, die geantwortet haben.

Die "readline lib" kannte ich bisher nicht und werde mir das einmal genauer ansehen.

Mir ging es aber zunächst darum, ob scanf im beschriebenen Sinne eingesetzt werden kann. Wie es aussieht, wohl eher
nicht. Ich möchte das Programm (welches ich unter Linux entwickle) auch per Crosscompiler Windowstauglich machen.
Ohne systemabhängige Methoden scheint es also nicht zu gehen. Im vorliegenden Fall ist es nicht so wichtig; ich wollte
eigentlich nur einen lästigen optischen Nebeneffekt verhindern (Cursor wandert in die nächste Zeile, wenn die
Returntaste ohne Eingabe betätigt wird). Ungültige Eingaben erkennt das Programm und löscht die Eingabezeile einfach wieder.
Also wollte ich z.b. einfach ein Blank vorgeben.
--
Gruß, Greetings
Claus Reibenstein
2022-05-07 21:24:07 UTC
Permalink
Post by Helmut Schellong
Post by Stefan Ram
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken
muss.
Ich denke nicht, daß dies mit Standard-C geht.
Ich auch nicht.
Post by Helmut Schellong
Es kann sich lohnen, die Beschreibung zu lesen und ein paar Versuche zu machen.
Es kann sich auch lohnen, die ursprüngliche Frage genau zu lesen, sie zu
verstehen und erst dann zu antworten.

Gruß
Claus
Helmut Schellong
2022-05-07 22:43:21 UTC
Permalink
Post by Claus Reibenstein
Post by Helmut Schellong
Post by Stefan Ram
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken
muss.
Ich denke nicht, daß dies mit Standard-C geht.
Ich auch nicht.
Post by Helmut Schellong
Es kann sich lohnen, die Beschreibung zu lesen und ein paar Versuche zu machen.
Es kann sich auch lohnen, die ursprüngliche Frage genau zu lesen, sie zu
verstehen und erst dann zu antworten.
Die ursprüngliche Frage ist:
|Ich möchte eine Eingabe für scanf vorgeben, so das man in der Konsole
|nur noch ohne weitere Eingabe die Returntaste drücken muss.

Ich bin offenbar der Einzige, der sie ernst genommen und verstanden hat,
einschließlich des Aufgabenstellers.

Ich wollte somit eine Lösung für _scanf_ verfolgen, wie es das Lastenheft vorgibt.
Wie sich herausstellte, ist diese Aufgabenstellung irrelevant.
(Lösungen ohne scanf (nicht kanonisch) hatte ich bereits in den 1980ern.)
Es gibt übrigens die Konversion '%\0'.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
Helmut Waitzmann
2022-05-08 04:57:16 UTC
Permalink
Post by Helmut Schellong
Post by Claus Reibenstein
Es kann sich auch lohnen, die ursprüngliche Frage genau zu lesen,
sie zu verstehen und erst dann zu antworten.
|Ich möchte eine Eingabe für scanf vorgeben, so das man in der
|Konsole nur noch ohne weitere Eingabe die Returntaste drücken
|muss.
Ich bin offenbar der Einzige, der sie ernst genommen und verstanden hat,
Du hast sie nicht erfasst, denn du hast den zweiten Teil der
Aufgabenstellung ignoriert.  Vollständig lautet die Aufgabenstellung
so:

«Ich möchte eine Eingabe für scanf vorgeben, sodass man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss.
puts/putchar schreiben offenbar nicht in den Buffer für scanf.»

Und jetzt kommt die entscheidende Frage, die du dir hättest stellen
müssen:  Was will der Aufgabensteller mit dem letzten Satz andeuten?

Antwort:  Er hat erstens erwartet, dass er mit puts/putchar den für
scanf zuständigen Eingabepuffer vor‐ausfüllen kann, damit er, wenn
er mit dem vorausgefüllten Eingabetext zufrieden ist, nur noch die
Returntaste drücken muss und dadurch trotzdem, obwohl er den
vorausgefüllten Text nicht selber eingetippt hat, beim Aufruf der
scanf‐Funktion ein Ergebnis erhält, als hätte er ihn eingetippt, und
zweitens erfahren, dass er das Vor‐Ausfüllen mit puts/putchar nicht
hinbekommt.
Post by Helmut Schellong
einschließlich des Aufgabenstellers.
Der Aufgabensteller hat im Gegensatz zu dir seine Frage verstanden. 
Nicht gewusst hat er jedoch, dass Eingabe von einem Terminal und
Ausgabe auf das Terminal zwei verschiedene Paar Schuhe sind, die,
obwohl beide ein sichtbares Resultat im Terminal hinterlassen (es
sei denn, man hätte das Terminal‐Echo abgeschaltet), nichts mit
einander zu tun haben.
Post by Helmut Schellong
Ich wollte somit eine Lösung für _scanf_ verfolgen, wie es das Lastenheft vorgibt.
Die richtige Antwort auf das Lastenheft wäre die folgende
zweigeteilte gewesen: 

(1.) Das von dir gewünschte geht nicht:  Man kann den
Terminal‐Eingabepuffer für zeilenweise Eingabe nicht durch eine
Ausgabe vor‐ausfüllen, weil Terminal‐Ein‐ und Ausgabe nichts mit
einander zu tun haben, obwohl es so aussieht, als hätten sie es. 
Deshalb muss

(2.) die von dir gewünschte Verbindung – im Eingabepuffer steht
jederzeit das, was auf dem Terminal geschrieben steht – vom Programm
selber simuliert werden.  Man schaltet dazu das Terminal in eine
Betriebsart um, die es dem Programm ermöglicht, jedes Zeichen, das
man tippt, sofort vom Terminal zu erhalten, obwohl man die
Returntaste noch gar nicht getippt hat.  Dann kann das Programm
entsprechend reagieren:  Ist das gelesene Zeichen ein druckbares
Zeichen, muss es erstens im simulierten Eingabepuffer abgelegt und
zweitens auf dem Terminal ausgegeben werden.  Ist es jedoch ein
Steuerzeichen – beispielsweise das, was das zuletzt eingetippte
Zeichen aus dem Eingabepuffer und vom sichtbaren Text im Terminal
löschen und die Schreibmarke eine Position zurücksetzen soll, muss
erstens das zuletzt im simulierten Eingabepuffer abgelegte Zeichen
aus dem simulierten Eingabepuffer entfernt werden und zweitens das
im Terminal sichtbare zuletzt eingetippte Zeichen mit einem
Leerzeichen überschrieben und die Position der Schreibmarke dorthin
gesetzt werden, wo das überschriebene Zeichen stand.  Das alles muss
man aber nicht selber programmieren, weil es dafür fertige Libraries
(readline, …) gibt.  Mit einem einfachen scanf ist es dabei nicht
mehr getan.
Helmut Schellong
2022-05-08 10:05:44 UTC
Permalink
Post by Helmut Schellong
Es kann sich auch lohnen, die ursprüngliche Frage genau zu lesen, sie zu verstehen und erst dann zu antworten.
|Ich möchte eine Eingabe für scanf vorgeben, so das man in der
|Konsole nur noch ohne weitere Eingabe die Returntaste drücken
|muss.
Ich bin offenbar der Einzige, der sie ernst genommen und verstanden hat,
«Ich möchte eine Eingabe für scanf vorgeben, sodass man in der Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss. puts/putchar schreiben offenbar nicht in den Buffer für scanf.»
Und jetzt kommt die entscheidende Frage, die du dir hättest stellen müssen:  Was will der Aufgabensteller mit dem letzten Satz andeuten?
Die Semantik des zweiten Satzes ist abstrus und nicht durchführbar, weshalb
ich mich auf den ersten Satz konzentrierte.

Eingabefunktionen stützen sich auf einen Eingabepuffer, der
vom Terminal gefüllt wird.
Dieser Puffer ist systemspezifisch irgendwo und nicht sichtbar.
Die Verwaltungsobjekte dazu sind intern und nicht zugänglich.

Mittels setvbuf() kann auf einen selbst angelegten Puffer gelenkt werden
und drei Modi der Pufferung angegeben werden.
Die Verwaltungsobjekte bleiben jedoch intern, so wie die Definition des Typs FILE.
Antwort:  Er hat erstens erwartet, dass er mit puts/putchar den für scanf zuständigen Eingabepuffer vor‐ausfüllen kann, damit er, wenn er mit dem vorausgefüllten Eingabetext zufrieden ist, nur noch die Returntaste drücken muss und dadurch trotzdem, obwohl er den vorausgefüllten Text nicht selber eingetippt hat, beim Aufruf der scanf‐Funktion ein Ergebnis erhält, als hätte er ihn eingetippt, und zweitens erfahren, dass er das Vor‐Ausfüllen mit puts/putchar nicht hinbekommt.
Post by Helmut Schellong
einschließlich des Aufgabenstellers.
Der Aufgabensteller hat im Gegensatz zu dir seine Frage verstanden.
Ja, aber er hat sein Verständnis nicht beschrieben.
Das (übliche) fast endlose Frage/Antwort-Spiel wollte ich nicht durchführen.
Nicht gewusst hat er jedoch, dass Eingabe von einem Terminal und Ausgabe auf das Terminal zwei verschiedene Paar Schuhe sind, die, obwohl beide ein sichtbares Resultat im Terminal hinterlassen (es sei denn, man hätte das Terminal‐Echo abgeschaltet), nichts mit einander zu tun haben.
Offensichtlich.
Es gibt nicht ohne Grund 'stdin' und 'stdout'.
Und fflush() ist z.B. nur auf 'stdout' anwendbar.
Post by Helmut Schellong
Ich wollte somit eine Lösung für _scanf_ verfolgen, wie es das Lastenheft vorgibt.
[...]

Vielleicht könnte ich das Problem tatsächlich allein mit scanf() hinbekommen.
Eventuell kann freopen() dabei helfen.

Jedenfalls habe ich bisher stets termio.h und termios.h benutzt, um
das Terminal umfassend zu konfigurieren.
Insbesondere für die Input-Sequenzen:
...
# define K_DEL (K_BASE+83)
# define K_U (K_BASE+72)
# define K_D (K_BASE+80)
# define K_R (K_BASE+77)
# define K_L (K_BASE+75)
# define K_N5 (K_BASE+76)
# define K_END (K_BASE+79)
# define K_PGD (K_BASE+81)
# define K_HOME (K_BASE+71)
# define K_PGU (K_BASE+73)
# define K_INS (K_BASE+82)
# define K_F1 (K_BASE+59)
...

n= read(fdg, ca, 6);
//...
CA0: c=ca[0], --n;
if ( n==2-1&&(c==K_CSI||c==K_ESC) ) n=0, c=ca[1]+K_BASE;
else if (n==3-1&& c==K_ESC&&(ca[1]=='['||ca[1]=='O'))
n=0, c=ca[2]+K_BASE;
else if (n>=4-1&&n<=5-1&& c==K_ESC&&ca[1]=='[') {
if (ca[n]=='~') {
if (n==4-1) n=0, c= ca[2]-'0'+'~'+K_BASE;
if (n==5-1) n=0, c=(ca[2]-'0')*10+ca[3]-'0'+'~'+K_BASE;
}
else if (n==4-1&&ca[2]=='[') n=0, c=ca[3]+K_BASE+'a'-'A';
}
return (N=n,I=1, c);


Es können bis zu 5 Zeichen eingehen aufgrund eines Tastendruckes.
Da hat man was zu tun, für sechs verschiedene BS.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
wolfgang bauer (D)
2022-05-08 17:29:31 UTC
Permalink
Post by Helmut Schellong
«Ich möchte eine Eingabe für scanf vorgeben, sodass man in der Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss. puts/putchar schreiben offenbar nicht in den Buffer für scanf.»
Und jetzt kommt die entscheidende Frage, die du dir hättest stellen müssen:  Was will der Aufgabensteller mit dem letzten Satz andeuten?
Die Semantik des zweiten Satzes ist abstrus und nicht durchführbar, weshalb
ich mich auf den ersten Satz konzentrierte.
Naja, auf den "Vorwurf" des Abstrusen muss ich dann doch nochmal antworten. Dein Vorredner (Helmut Waitzmann) hat den Kern meiner Frage erfasst und nochmal
herausgestellt. So abstrus kann meine Formulierung nicht gewesen sein. Auch andere haben verstanden, worum es mir ging.
Post by Helmut Schellong
Der Aufgabensteller hat im Gegensatz zu dir seine Frage verstanden.
Ja, aber er hat sein Verständnis nicht beschrieben.
Doch, das habe ich.
Post by Helmut Schellong
Das (übliche) fast endlose Frage/Antwort-Spiel wollte ich nicht durchführen.
Und genau darum, um das Pingpong zu vermeiden, habe ich den Kern meiner Frage (zum *Vestaendnis* bzgl. des scanf-Mechanismus') nochmal unterstrichen,
indem ich meine Erwartung zu puts/putchar beschrieb, die ja dann nicht erfüllt wurde.

Danke nochmal an die Beteiligten für die Ausführungen, denen ich einiges entnehmen konnte. So oft programmiere ich nicht für die Konsole und habe daher
noch einiges zu lernen. Bis auf simpelste Ein- und Ausgaben habe ich da noch nicht viel gemacht. Ansonsten versehe ich meine Programme mit einem GUI.
--
Gruß, Greetings
Helmut Schellong
2022-05-08 18:56:02 UTC
Permalink
Post by wolfgang bauer (D)
Post by Helmut Schellong
«Ich möchte eine Eingabe für scanf vorgeben, sodass man in der Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss. puts/putchar schreiben offenbar nicht in den Buffer für scanf.»
Und jetzt kommt die entscheidende Frage, die du dir hättest stellen müssen:  Was will der Aufgabensteller mit dem letzten Satz andeuten?
Die Semantik des zweiten Satzes ist abstrus und nicht durchführbar, weshalb
ich mich auf den ersten Satz konzentrierte.
Naja, auf den "Vorwurf" des Abstrusen muss ich dann doch nochmal antworten. Dein Vorredner (Helmut Waitzmann) hat den Kern meiner Frage erfasst und nochmal
herausgestellt. So abstrus kann meine Formulierung nicht gewesen sein. Auch andere haben verstanden, worum es mir ging.
puts/putchar _können nicht_ in den scanf-Puffer schreiben.
Niemand kann in diesen Puffer schreiben, weil der intern ist.
Dieser Gedanke, diese Vorstellung ist von Grund auf abstrus.
Post by wolfgang bauer (D)
Post by Helmut Schellong
Der Aufgabensteller hat im Gegensatz zu dir seine Frage verstanden.
Ja, aber er hat sein Verständnis nicht beschrieben.
Doch, das habe ich.
Einige Postings später kam die Info, daß der Cursor durch scanf
unerwünscht in die nächste Zeile ging.

Genau das sind hilfreiche Detailinformationen, die die Lösung näher bringen.
Kamen aber viel zu knapp.
Post by wolfgang bauer (D)
Post by Helmut Schellong
Das (übliche) fast endlose Frage/Antwort-Spiel wollte ich nicht durchführen.
Und genau darum, um das Pingpong zu vermeiden, habe ich den Kern meiner Frage (zum *Vestaendnis* bzgl. des scanf-Mechanismus') nochmal unterstrichen,
indem ich meine Erwartung zu puts/putchar beschrieb, die ja dann nicht erfüllt wurde.
puts/putchar sind Ausgabefunktionen, scanf eine Eingabefunktion.
In der Summe sind die Informationen daher für mich abstrus (verworren, unbegreiflich)
gewesen, weshalb ich mich auf den ersten Satz konzentrierte, der nicht abstrus ist.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
wolfgang bauer (D)
2022-05-08 19:30:35 UTC
Permalink
Post by Helmut Schellong
Post by wolfgang bauer (D)
Post by Helmut Schellong
Die Semantik des zweiten Satzes ist abstrus und nicht durchführbar, weshalb
ich mich auf den ersten Satz konzentrierte.
Naja, auf den "Vorwurf" des Abstrusen muss ich dann doch nochmal antworten. Dein Vorredner (Helmut Waitzmann) hat den Kern meiner Frage erfasst und nochmal
herausgestellt. So abstrus kann meine Formulierung nicht gewesen sein. Auch andere haben verstanden, worum es mir ging.
puts/putchar _können nicht_ in den scanf-Puffer schreiben.
Niemand kann in diesen Puffer schreiben, weil der intern ist.
Dieser Gedanke, diese Vorstellung ist von Grund auf abstrus.
Mit Verlaub, aber sinnentnehmend lesen und mitdenken liegt dir nicht. Bist du auf Konfrontationskurs ?

Meine Frage stellte ich ja gerade darum, *WEIL* ich da noch eine Frage hatte. Ich erkläre dir gerade, das 1+1=2 ist.
Post by Helmut Schellong
Einige Postings später kam die Info, daß der Cursor durch scanf
unerwünscht  in die nächste Zeile ging.
Genau das sind hilfreiche Detailinformationen, die die Lösung näher bringen.
Kamen aber viel zu knapp.
Für andere nicht. Für dich schon. Das liegt aber nicht an mir. Du solltest lernen, dein
überschäumendes Temperament zu zügeln. Sonst hast du genau die Offtopic-Exzesse, die du
doch vermeiden wolltest.
Post by Helmut Schellong
Post by wolfgang bauer (D)
Post by Helmut Schellong
Das (übliche) fast endlose Frage/Antwort-Spiel wollte ich nicht durchführen.
Und genau darum, um das Pingpong zu vermeiden, habe ich den Kern meiner Frage (zum *Vestaendnis* bzgl. des scanf-Mechanismus') nochmal unterstrichen,
indem ich meine Erwartung zu puts/putchar beschrieb, die ja dann nicht erfüllt wurde.
puts/putchar sind Ausgabefunktionen, scanf eine Eingabefunktion.
In der Summe sind die Informationen daher für mich abstrus (verworren, unbegreiflich)
gewesen, weshalb ich mich auf den ersten Satz konzentrierte, der nicht abstrus ist.
Nein. Du denkst nicht mit und wirfst dann mit Formulierungen um dich, die man nicht einfach so stehen lassen kann.

Kehren wir zum Thema zurück, wobei das Problem längst gelöst ist. Siehe <t56f20$gvv$***@dont-email.me>
--
Gruß, Greetings
Juergen Ilse
2022-05-08 15:01:02 UTC
Permalink
Hallo,
Post by Helmut Waitzmann
Post by Helmut Schellong
Post by Claus Reibenstein
Es kann sich auch lohnen, die ursprüngliche Frage genau zu lesen,
sie zu verstehen und erst dann zu antworten.
|Ich möchte eine Eingabe für scanf vorgeben, so das man in der
|Konsole nur noch ohne weitere Eingabe die Returntaste drücken
|muss.
Ich bin offenbar der Einzige, der sie ernst genommen und verstanden hat,
Du hast sie nicht erfasst, denn du hast den zweiten Teil der
Aufgabenstellung ignoriert.  Vollständig lautet die Aufgabenstellung
Ich muss mich entschuldigen, ich habe auch zu oberflaechlich drueber
hinweg gelesen. Ich hatte an den Fall gedacht, dass man eine Eingabe
Zeichen fuer Zeichen einlesen moechte, ohne erst auf <return> zu warten,
und dazu muss man aauf passende libraries zurueckgreifen, oder man wird
*sehr* systemabhaengig.
Fuer den Fall des Threadstarters iist vermutlich tatsaechlich libreadline
der passendste Weg, wenn die librar fuer alle Zielsysteme zur Verfuegung
steht.

Tschuess,
Juergen Ilse (***@useenet-verwaltung.de)
Juergen Ilse
2022-05-08 14:55:55 UTC
Permalink
Hallo,
Post by Helmut Schellong
Post by Claus Reibenstein
Post by Helmut Schellong
Post by Stefan Ram
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken
muss.
Ich denke nicht, daß dies mit Standard-C geht.
Ich auch nicht.
Post by Helmut Schellong
Es kann sich lohnen, die Beschreibung zu lesen und ein paar Versuche zu machen.
Es kann sich auch lohnen, die ursprüngliche Frage genau zu lesen, sie zu
verstehen und erst dann zu antworten.
|Ich möchte eine Eingabe für scanf vorgeben, so das man in der Konsole
|nur noch ohne weitere Eingabe die Returntaste drücken muss.
Ja, und da bei so ziemlich allen gaengigen Desktopsystemen dere Terminal
Treiber per default ein line-buffering macht (die eingabe alsso erst nach
Abschluss der Zeile in den input stream weiter gibt), muesste auch das
Verhaltwen des Terminal Treibers aendern. Das koennte man unter unixoiden
Systemen z.B, mittels libtermcap oder libtermio machen. Oder portabler
mittels einer libcurses (die ihrerseits auf dem System auf eine der beiden
oben genannten librarys oder auf Systemen, die das nicht kennen auf system-
spezifische Funktionen aufsetzt).
Post by Helmut Schellong
Ich bin offenbar der Einzige, der sie ernst genommen und verstanden hat,
einschließlich des Aufgabenstellers.
Eibildung ist auch eine Bildung ...

Tscchuess,
Juergen Ilse (juergenqusenet-vewaltung.de)
Thomas Koenig
2022-05-08 15:14:31 UTC
Permalink
Post by Juergen Ilse
Eibildung ist auch eine Bildung ...
Sowieso, die Frage ist nur noch, ob Spiegel- oder Rührei...
Thomas Noll
2022-05-08 16:29:55 UTC
Permalink
Post by Juergen Ilse
Hallo,
Post by Helmut Schellong
|Ich möchte eine Eingabe für scanf vorgeben, so das man in der Konsole
|nur noch ohne weitere Eingabe die Returntaste drücken muss.
Ja, und da bei so ziemlich allen gaengigen Desktopsystemen dere Terminal
Treiber per default ein line-buffering macht (die eingabe alsso erst nach
Abschluss der Zeile in den input stream weiter gibt), muesste auch das
Verhaltwen des Terminal Treibers aendern.
Ich würde ja mal sagen, daß das explizit gewünschte Drücken der Returntaste
die Zeile abschließt.
--
Dummheit und Gewissheit sind siamesische Zwillinge.
Ganz sicher!
Helmut Schellong
2022-05-08 18:41:29 UTC
Permalink
Post by Thomas Noll
Post by Juergen Ilse
Hallo,
Post by Helmut Schellong
|Ich möchte eine Eingabe für scanf vorgeben, so das man in der Konsole
|nur noch ohne weitere Eingabe die Returntaste drücken muss.
Ja, und da bei so ziemlich allen gaengigen Desktopsystemen dere Terminal
Treiber per default ein line-buffering macht (die eingabe alsso erst nach
Abschluss der Zeile in den input stream weiter gibt), muesste auch das
Verhaltwen des Terminal Treibers aendern.
Ich würde ja mal sagen, daß das explizit gewünschte Drücken der Returntaste
die Zeile abschließt.
Ja, deshalb schrieb ich auch, daß Versuche mit scanf eventuell das Problem lösen.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
Stefan Ram
2022-05-07 18:29:38 UTC
Permalink
Post by Stefan Ram
while( p < top && ch != '\n' )*p++ = ch =( char )getchar();
Die folgende, neue Version erlaubt es nun immerhin,
die Eingabezeile wie bei Verwendung von "scanf" noch
zu bearbeiten, bevor die Eingabetaste gedrückt wird.

#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 4096
#define xstr(a) str(a)
#define str(a) #a

int main( void )
{ char input[ BUFFER_SIZE ];
const char * const top = input + BUFFER_SIZE;
printf( "Zahl (Eingabetaste fuer 0)? " );
fgets( input, BUFFER_SIZE, stdin );
if( *input == '\n' )
{ puts( "Eingabetaste erkannt." );
strncpy( input, "0\n", BUFFER_SIZE-1 ); }
for( char * p = input; p < top && *p; ++p )
if( *p == '\n' ){ *p = 0; break; }
printf( "Eingabe = \"%." xstr( BUFFER_SIZE ) "s\"\n", input ); }
wolfgang bauer (D)
2022-05-07 18:50:39 UTC
Permalink
Post by Stefan Ram
Post by Stefan Ram
while( p < top && ch != '\n' )*p++ = ch =( char )getchar();
Die folgende, neue Version erlaubt es nun immerhin,
die Eingabezeile wie bei Verwendung von "scanf" noch
zu bearbeiten, bevor die Eingabetaste gedrückt wird.
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 4096
#define xstr(a) str(a)
#define str(a) #a
int main( void )
{ char input[ BUFFER_SIZE ];
const char * const top = input + BUFFER_SIZE;
printf( "Zahl (Eingabetaste fuer 0)? " );
fgets( input, BUFFER_SIZE, stdin );
if( *input == '\n' )
{ puts( "Eingabetaste erkannt." );
strncpy( input, "0\n", BUFFER_SIZE-1 ); }
for( char * p = input; p < top && *p; ++p )
if( *p == '\n' ){ *p = 0; break; }
printf( "Eingabe = \"%." xstr( BUFFER_SIZE ) "s\"\n", input ); }
Das erledigt genau, was ich brauche ! Danke :-)
--
Gruß, Greetings
Juergen Ilse
2022-05-08 14:48:38 UTC
Permalink
Hallo,
Post by Stefan Ram
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken
muss.
Ich denke nicht, daß dies mit Standard-C geht.
Da hasst du wohl recht.
Post by Stefan Ram
Vielleicht geht es mit speziellen Konsolen-Funktionen,
aber dann wäre es nicht portabel. (Frage zum Beispiel
in einer Windows-Newsgroup danach.)
Das portabelste in dieser Richtung duerfte meiens Erachtens nach die curses
librar sein, da die auf so ziemlich jedes halbwegs gaengige Desktop System
portiert wurde und auch in so ziemlich allen unixoiden Systemen verfuegbar
ist.
Post by Stefan Ram
Was vielleicht geht, wäre es, bei einer "leeren" Eingabe
eine Vorgabe zu verwenden.
Ich fuerchte, das wird nicht funktionieren.

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
Juergen Ilse
2022-05-08 14:44:59 UTC
Permalink
Hallo,
Post by wolfgang bauer (D)
Ich möchte eine Eingabe für scanf vorgeben, so das man in der Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss.
puts/putchar schreiben offenbar nicht in den Buffer für scanf.
Damit das funktioiert, muesstest du auch den TerminalModus passend schalten,
denn per default ist der vermutlich line buffered, so dass erst nach Abschluss
der Zeile die Zeile vom Terminal in die input queue uebertragen wird. Wenn
du das alles moeglichst portabel hinbekommen moechtest, lohnt sich ein Blick
aauf die Funktionen der "curses" library. Portabler als das wirst du es wohl
kaum hinbekommen ...

Tschuess,
Juergen Ilse (***@usenet-verwaöltung.de)
wolfgang bauer (D)
2022-05-08 17:41:31 UTC
Permalink
Post by Juergen Ilse
Post by wolfgang bauer (D)
puts/putchar schreiben offenbar nicht in den Buffer für scanf.
Damit das funktioiert, muesstest du auch den TerminalModus passend schalten,
denn per default ist der vermutlich line buffered, so dass erst nach Abschluss
der Zeile die Zeile vom Terminal in die input queue uebertragen wird. Wenn
du das alles moeglichst portabel hinbekommen moechtest, lohnt sich ein Blick
aauf die Funktionen der "curses" library. Portabler als das wirst du es wohl
kaum hinbekommen ...
Danke für den Tip. Auch diese Library, neben der schon vorgeschlagenen readline-Library, werde ich mir einmal
genauer ansehen.
--
Gruß, Greetings
Helmut Schellong
2022-05-08 19:04:50 UTC
Permalink
Post by wolfgang bauer (D)
Post by Juergen Ilse
Post by wolfgang bauer (D)
puts/putchar schreiben offenbar nicht in den Buffer für scanf.
Damit das funktioiert, muesstest du auch den TerminalModus passend schalten,
denn per default ist der vermutlich line buffered, so dass erst nach Abschluss
der Zeile die Zeile vom Terminal in die input queue uebertragen wird. Wenn
du das alles moeglichst portabel hinbekommen moechtest, lohnt sich ein Blick
aauf die Funktionen der "curses" library. Portabler als das wirst du es wohl
kaum hinbekommen ...
Danke für den Tip. Auch diese Library, neben der schon vorgeschlagenen readline-Library, werde ich mir einmal
genauer ansehen.
termio.h, termios.h, read(), etc. sind im POSIX-Standard enthalten.
Ich konnte damit alle Unix-Systeme und Windows mit Einzeltasten-Lesen ausstatten.
Im POSIX ist übrigens auch der C-Standard enthalten.

Der Aufwand damit dürfte 5-30-fach geringer sein als mit genannten Libraries
curses oder readline.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
wolfgang bauer (D)
2022-05-08 19:32:17 UTC
Permalink
Post by Helmut Schellong
termio.h, termios.h, read(), etc. sind im POSIX-Standard enthalten.
Ich konnte damit alle Unix-Systeme und Windows mit Einzeltasten-Lesen ausstatten.
Im POSIX ist übrigens auch der C-Standard enthalten.
Der Aufwand damit dürfte 5-30-fach geringer sein als mit genannten Libraries
curses oder readline.
Danke, auch das ist notiert und steht nun auf meiner Todo-Liste.
--
Gruß, Greetings
Juergen Ilse
2022-05-09 11:46:25 UTC
Permalink
Hallo,
Post by Helmut Schellong
Post by wolfgang bauer (D)
Post by Juergen Ilse
Post by wolfgang bauer (D)
puts/putchar schreiben offenbar nicht in den Buffer für scanf.
Damit das funktioiert, muesstest du auch den TerminalModus passend schalten,
denn per default ist der vermutlich line buffered, so dass erst nach Abschluss
der Zeile die Zeile vom Terminal in die input queue uebertragen wird. Wenn
du das alles moeglichst portabel hinbekommen moechtest, lohnt sich ein Blick
aauf die Funktionen der "curses" library. Portabler als das wirst du es wohl
kaum hinbekommen ...
Danke für den Tip. Auch diese Library, neben der schon vorgeschlagenen readline-Library, werde ich mir einmal
genauer ansehen.
termio.h, termios.h, read(), etc. sind im POSIX-Standard enthalten.
Ich konnte damit alle Unix-Systeme und Windows mit Einzeltasten-Lesen ausstatten.
Im POSIX ist übrigens auch der C-Standard enthalten.
Es gibt noch unixoide Systeme, die nicht sowohl termio.h als auch termios.h
enthalten. Auf aelteren unixoiden Sstemen (die nicht unbedingt posix konform
sind) findet man manchmal per default sogar nur termcap.h. Um das sstem-
uebergreifeend kompatibel zu halten, muss man einen erheblichen Aufwand mit
bedingter Compilierung treiben. Die libcurses existiert jedoch auf nahezu
*allen* unixoiden Systemen, denn sie ist eine Abstraktion der eher low level
Funktionen von termio, termios und termcap.
Post by Helmut Schellong
Der Aufwand damit dürfte 5-30-fach geringer sein als mit genannten Libraries
curses oder readline.
Das ist voelliger Unfug. Da ja mehr als ein bischen "Cursorsteuerung" getan
werden soll, sondern eine input-routine mit "Vorgabe" und "Editierfunktion"
implementiert werden soll, ist libreadline (die das alles bereits enthaelt
mit Sicherheit die Version, die weniger Aufwand kostet, als alles von Grund
auf neu zu implementieren. Allerdings sollte man (wenn man die Softwae
weiterzugeben gedenkt) ggfs. auf die Lienzen achten (steht die libreadline
unter GPL oder LGPL? Unter welcher Lizenz soll die neue Software stehen?).

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
Helmut Schellong
2022-05-09 15:37:43 UTC
Permalink
Post by Juergen Ilse
Hallo,
Post by Helmut Schellong
Post by wolfgang bauer (D)
Post by Juergen Ilse
Post by wolfgang bauer (D)
puts/putchar schreiben offenbar nicht in den Buffer für scanf.
Damit das funktioiert, muesstest du auch den TerminalModus passend schalten,
denn per default ist der vermutlich line buffered, so dass erst nach Abschluss
der Zeile die Zeile vom Terminal in die input queue uebertragen wird. Wenn
du das alles moeglichst portabel hinbekommen moechtest, lohnt sich ein Blick
aauf die Funktionen der "curses" library. Portabler als das wirst du es wohl
kaum hinbekommen ...
Danke für den Tip. Auch diese Library, neben der schon vorgeschlagenen readline-Library, werde ich mir einmal
genauer ansehen.
termio.h, termios.h, read(), etc. sind im POSIX-Standard enthalten.
Ich konnte damit alle Unix-Systeme und Windows mit Einzeltasten-Lesen ausstatten.
Im POSIX ist übrigens auch der C-Standard enthalten.
Es gibt noch unixoide Systeme, die nicht sowohl termio.h als auch termios.h
enthalten. Auf aelteren unixoiden Sstemen (die nicht unbedingt posix konform
sind) findet man manchmal per default sogar nur termcap.h. Um das sstem-
uebergreifeend kompatibel zu halten, muss man einen erheblichen Aufwand mit
bedingter Compilierung treiben. Die libcurses existiert jedoch auf nahezu
*allen* unixoiden Systemen, denn sie ist eine Abstraktion der eher low level
Funktionen von termio, termios und termcap.
Post by Helmut Schellong
Der Aufwand damit dürfte 5-30-fach geringer sein als mit genannten Libraries
curses oder readline.
Das ist voelliger Unfug. Da ja mehr als ein bischen "Cursorsteuerung" getan
werden soll, sondern eine input-routine mit "Vorgabe" und "Editierfunktion"
implementiert werden soll, ist libreadline (die das alles bereits enthaelt
mit Sicherheit die Version, die weniger Aufwand kostet, als alles von Grund
auf neu zu implementieren. Allerdings sollte man (wenn man die Softwae
weiterzugeben gedenkt) ggfs. auf die Lienzen achten (steht die libreadline
unter GPL oder LGPL? Unter welcher Lizenz soll die neue Software stehen?).
Ich kann da mit konkreter Realität antworten:

Seit den 1980ern habe ich mit termio.h oder termios.h das Tastendruck-Operieren realisiert.
Ich benötige zum Konfigurieren (hin und her) des Terminals etwa 5 Zeilen.
Ich finde das sehr wenig.
Eine Funktion Getch() habe ich entwickelt, um deren Tastenwert einem switch zuzuführen.
Diese Funktion habe ich bereits zu 90% gepostet - einige wenige Zeilen.
Ich finde den geschilderten Aufwand tiny.
Funktionen wie ioctl(), read(), ... sind in der libc enthalten.

Cursor-Steuerung und ähnlich muß stets explizit mittels entsprechender Befehle
implementiert werden - weil: hellseherische Fähigkeiten gibt es da nicht.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
Juergen Ilse
2022-05-09 15:54:58 UTC
Permalink
Hallo,
Post by Helmut Schellong
Post by Juergen Ilse
Post by Helmut Schellong
termio.h, termios.h, read(), etc. sind im POSIX-Standard enthalten.
Ich konnte damit alle Unix-Systeme und Windows mit Einzeltasten-Lesen ausstatten.
Im POSIX ist übrigens auch der C-Standard enthalten.
Aber nicht umgekeht, und es war zu Begin des Tnreads nach Loesungen im Rahmen
des C-Standards die Rede ...
Post by Helmut Schellong
Post by Juergen Ilse
Es gibt noch unixoide Systeme, die nicht sowohl termio.h als auch termios.h
enthalten. Auf aelteren unixoiden Sstemen (die nicht unbedingt posix konform
sind) findet man manchmal per default sogar nur termcap.h. Um das sstem-
uebergreifeend kompatibel zu halten, muss man einen erheblichen Aufwand mit
bedingter Compilierung treiben. Die libcurses existiert jedoch auf nahezu
*allen* unixoiden Systemen, denn sie ist eine Abstraktion der eher low level
Funktionen von termio, termios und termcap.
Post by Helmut Schellong
Der Aufwand damit dürfte 5-30-fach geringer sein als mit genannten Libraries
curses oder readline.
Das ist voelliger Unfug. Da ja mehr als ein bischen "Cursorsteuerung" getan
werden soll, sondern eine input-routine mit "Vorgabe" und "Editierfunktion"
implementiert werden soll, ist libreadline (die das alles bereits enthaelt
mit Sicherheit die Version, die weniger Aufwand kostet, als alles von Grund
auf neu zu implementieren. Allerdings sollte man (wenn man die Softwae
weiterzugeben gedenkt) ggfs. auf die Lienzen achten (steht die libreadline
unter GPL oder LGPL? Unter welcher Lizenz soll die neue Software stehen?).
Seit den 1980ern habe ich mit termio.h oder termios.h das Tastendruck-Operieren realisiert.
Ich benötige zum Konfigurieren (hin und her) des Terminals etwa 5 Zeilen.
Ich finde das sehr wenig.
Es ging aber nicht nur um das konfigurieren des Terminals, sondern um die
Loesung der Aufgabe des Threadstarters. Das lief dann letztendlich auf
so etwas wie einen "Eingabe-Editor mit Antwortvorgabe" hinaus. Die
libreadline enthaeelt bereits die gesamte Funktionalitaet, die low-level
Terminal-Routinen *ausschliesslich* die Terminal-Steuerung, waehrend alles
andere dann "von Hand" neu zu programmieren waere.

libcurses abstrahiert die Terminalsteuerung (so dass einfache Faelle von
"Terminal-Mode umsetzen" ggfs. sogar geringfuegig aufwendiger sein koennten.
Sobald die Anforderungen etwas umfangreicher werden, hat aber curses bei
wachsender Komplexistaet immermehr Vorteile.

Tschuess,
Juergen Ilse (juergenqusenet-verwaltung.de)
Helmut Schellong
2022-05-09 16:53:27 UTC
Permalink
Post by Juergen Ilse
Hallo,
Post by Helmut Schellong
Post by Juergen Ilse
Post by Helmut Schellong
termio.h, termios.h, read(), etc. sind im POSIX-Standard enthalten.
Ich konnte damit alle Unix-Systeme und Windows mit Einzeltasten-Lesen ausstatten.
Im POSIX ist übrigens auch der C-Standard enthalten.
Aber nicht umgekeht, und es war zu Begin des Tnreads nach Loesungen im Rahmen
des C-Standards die Rede ...
Ja, und ich wollte das dementsprechend per scanf lösen.
Dann bekam ich aber Schimpfe, ich hätte alles falsch verstanden, und das
erste Posting sagte bereits, daß das in Standard-C nicht lösbar sei.
Post by Juergen Ilse
Post by Helmut Schellong
Post by Juergen Ilse
Es gibt noch unixoide Systeme, die nicht sowohl termio.h als auch termios.h
enthalten. Auf aelteren unixoiden Sstemen (die nicht unbedingt posix konform
sind) findet man manchmal per default sogar nur termcap.h. Um das sstem-
uebergreifeend kompatibel zu halten, muss man einen erheblichen Aufwand mit
bedingter Compilierung treiben. Die libcurses existiert jedoch auf nahezu
*allen* unixoiden Systemen, denn sie ist eine Abstraktion der eher low level
Funktionen von termio, termios und termcap.
Post by Helmut Schellong
Der Aufwand damit dürfte 5-30-fach geringer sein als mit genannten Libraries
curses oder readline.
Das ist voelliger Unfug. Da ja mehr als ein bischen "Cursorsteuerung" getan
werden soll, sondern eine input-routine mit "Vorgabe" und "Editierfunktion"
implementiert werden soll, ist libreadline (die das alles bereits enthaelt
mit Sicherheit die Version, die weniger Aufwand kostet, als alles von Grund
auf neu zu implementieren. Allerdings sollte man (wenn man die Softwae
weiterzugeben gedenkt) ggfs. auf die Lienzen achten (steht die libreadline
unter GPL oder LGPL? Unter welcher Lizenz soll die neue Software stehen?).
Seit den 1980ern habe ich mit termio.h oder termios.h das Tastendruck-Operieren realisiert.
Ich benötige zum Konfigurieren (hin und her) des Terminals etwa 5 Zeilen.
Ich finde das sehr wenig.
Es ging aber nicht nur um das konfigurieren des Terminals, sondern um die
Loesung der Aufgabe des Threadstarters. Das lief dann letztendlich auf
so etwas wie einen "Eingabe-Editor mit Antwortvorgabe" hinaus. Die
libreadline enthaeelt bereits die gesamte Funktionalitaet, die low-level
Terminal-Routinen *ausschliesslich* die Terminal-Steuerung, waehrend alles
andere dann "von Hand" neu zu programmieren waere.
Bei mir ist das dann so etwas:
writef(FDWR, "\033[0m\033[D");
Finde ich ganz simpel: ANSI-Sequenzen zur Terminalsteuerung.
Post by Juergen Ilse
libcurses abstrahiert die Terminalsteuerung (so dass einfache Faelle von
"Terminal-Mode umsetzen" ggfs. sogar geringfuegig aufwendiger sein koennten.
Sobald die Anforderungen etwas umfangreicher werden, hat aber curses bei
wachsender Komplexistaet immermehr Vorteile.
Ja, bei hoher Komplexität hat curses Vorteile.
Ich kenne curses, habe in den 1990ern mich damit mal befaßt.

Ich fand folgendes aber insgesamt angemessener:

//...
case K_U :
case K_PGU :
if (udpos<=0) goto JBEEP;
if (c==K_U) --udpos;
if (c==K_PGU) udpos-=nud;
if (udpos<0) udpos=0;
goto DWNGZ;
case K_D :
case K_PGD :
if (udpos>=nzeil) goto JBEEP;
if (c==K_D) ++udpos;
if (c==K_PGD) udpos+=nud;
if (udpos>=nzeil) { udpos=nzeil; goto KESC; }
DWNGZ:;
zi= GetZ(Zeile, udpos);
cup=Cup;
break;
case K_L :
if (cup>0) CursLR(-1), Cup=--cup;
continue;
case K_R :
if (cup<zi) CursLR(1), Cup=++cup;
continue;
case K_PGUt:
case K_HOME:
cup=0;
//...
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
Juergen Ilse
2022-05-09 19:14:08 UTC
Permalink
Post by Helmut Schellong
Post by Juergen Ilse
Post by Helmut Schellong
Post by Juergen Ilse
Das ist voelliger Unfug. Da ja mehr als ein bischen "Cursorsteuerung" getan
werden soll, sondern eine input-routine mit "Vorgabe" und "Editierfunktion"
implementiert werden soll, ist libreadline (die das alles bereits enthaelt
mit Sicherheit die Version, die weniger Aufwand kostet, als alles von Grund
auf neu zu implementieren. Allerdings sollte man (wenn man die Softwae
weiterzugeben gedenkt) ggfs. auf die Lienzen achten (steht die libreadline
unter GPL oder LGPL? Unter welcher Lizenz soll die neue Software stehen?).
Seit den 1980ern habe ich mit termio.h oder termios.h das Tastendruck-Operieren realisiert.
Ich benötige zum Konfigurieren (hin und her) des Terminals etwa 5 Zeilen.
Ich finde das sehr wenig.
Es ging aber nicht nur um das konfigurieren des Terminals, sondern um die
Loesung der Aufgabe des Threadstarters. Das lief dann letztendlich auf
so etwas wie einen "Eingabe-Editor mit Antwortvorgabe" hinaus. Die
libreadline enthaeelt bereits die gesamte Funktionalitaet, die low-level
Terminal-Routinen *ausschliesslich* die Terminal-Steuerung, waehrend alles
andere dann "von Hand" neu zu programmieren waere.
writef(FDWR, "\033[0m\033[D");
Finde ich ganz simpel: ANSI-Sequenzen zur Terminalsteuerung.
Es gibt mehr als nur ANSI Terminals (sogar richtigin der Praxis aktiv
verwendet), und manche sind sogar in keiner Weise ANSI kompatibel ...
Die von dir hier praesentierte Methode ist also alles andere als portabel,
im Gegensatz zu cureses oder readline (da beide libraries die notwendigen
Funktionen soweit wie moeglich *portabel* fuer diverse Terminaltypen um-
setzen und nicht nur fuer ein einziges).
Post by Helmut Schellong
Post by Juergen Ilse
libcurses abstrahiert die Terminalsteuerung (so dass einfache Faelle von
"Terminal-Mode umsetzen" ggfs. sogar geringfuegig aufwendiger sein koennten.
Sobald die Anforderungen etwas umfangreicher werden, hat aber curses bei
wachsender Komplexistaet immermehr Vorteile.
Ja, bei hoher Komplexität hat curses Vorteile.
Ich kenne curses, habe in den 1990ern mich damit mal befaßt.
//...
if (udpos<=0) goto JBEEP;
if (c==K_U) --udpos;
if (c==K_PGU) udpos-=nud;
if (udpos<0) udpos=0;
goto DWNGZ;
if (udpos>=nzeil) goto JBEEP;
if (c==K_D) ++udpos;
if (c==K_PGD) udpos+=nud;
if (udpos>=nzeil) { udpos=nzeil; goto KESC; }
DWNGZ:;
zi= GetZ(Zeile, udpos);
cup=Cup;
break;
if (cup>0) CursLR(-1), Cup=--cup;
continue;
if (cup<zi) CursLR(1), Cup=++cup;
continue;
cup=0;
//...
Warum? Weil du diesen Kram selbst gebastelt hast? In realen Programmen
ist man IMHO mit curses *erheblich* besser bedient. Und ein vollstaendiger
Eoingabe editor (wie ihn libreadline bietet) ist das bei weitem auch noch
nicht ...

Tschuess,
Juergen Ilse (juergenqusenet-verwaltung.de)
Helmut Schellong
2022-05-09 20:40:34 UTC
Permalink
Post by Juergen Ilse
Post by Helmut Schellong
Post by Juergen Ilse
Post by Helmut Schellong
Post by Juergen Ilse
Das ist voelliger Unfug. Da ja mehr als ein bischen "Cursorsteuerung" getan
werden soll, sondern eine input-routine mit "Vorgabe" und "Editierfunktion"
implementiert werden soll, ist libreadline (die das alles bereits enthaelt
mit Sicherheit die Version, die weniger Aufwand kostet, als alles von Grund
auf neu zu implementieren. Allerdings sollte man (wenn man die Softwae
weiterzugeben gedenkt) ggfs. auf die Lienzen achten (steht die libreadline
unter GPL oder LGPL? Unter welcher Lizenz soll die neue Software stehen?).
Seit den 1980ern habe ich mit termio.h oder termios.h das Tastendruck-Operieren realisiert.
Ich benötige zum Konfigurieren (hin und her) des Terminals etwa 5 Zeilen.
Ich finde das sehr wenig.
Es ging aber nicht nur um das konfigurieren des Terminals, sondern um die
Loesung der Aufgabe des Threadstarters. Das lief dann letztendlich auf
so etwas wie einen "Eingabe-Editor mit Antwortvorgabe" hinaus. Die
libreadline enthaeelt bereits die gesamte Funktionalitaet, die low-level
Terminal-Routinen *ausschliesslich* die Terminal-Steuerung, waehrend alles
andere dann "von Hand" neu zu programmieren waere.
writef(FDWR, "\033[0m\033[D");
Finde ich ganz simpel: ANSI-Sequenzen zur Terminalsteuerung.
Es gibt mehr als nur ANSI Terminals (sogar richtigin der Praxis aktiv
verwendet), und manche sind sogar in keiner Weise ANSI kompatibel ...
Die von dir hier praesentierte Methode ist also alles andere als portabel,
im Gegensatz zu cureses oder readline (da beide libraries die notwendigen
Funktionen soweit wie moeglich *portabel* fuer diverse Terminaltypen um-
setzen und nicht nur fuer ein einziges).
Ich habe seit den 1980ern _nur_ ANSI-Terminals kennengelernt (15..20).
Falls ich einmal unbedingt mit einem Nicht-ANSI-Terminal klarkommen
müßte, würde ich wohl curses verwenden.
Das ist angesichts der Realität jedoch äußerst unwahrscheinlich.

Ich war also _nur_ mit ANSI-Terminals konfrontiert.
Und alle diese sind untereinander fast identisch bei den Sequenzen!
ANSI-Sequenzen sind ja schließlich von ANSI _standardisierte_ Sequenzen.
Post by Juergen Ilse
Post by Helmut Schellong
Post by Juergen Ilse
libcurses abstrahiert die Terminalsteuerung (so dass einfache Faelle von
"Terminal-Mode umsetzen" ggfs. sogar geringfuegig aufwendiger sein koennten.
Sobald die Anforderungen etwas umfangreicher werden, hat aber curses bei
wachsender Komplexistaet immermehr Vorteile.
Ja, bei hoher Komplexität hat curses Vorteile.
Ich kenne curses, habe in den 1990ern mich damit mal befaßt.
//...
if (udpos<=0) goto JBEEP;
if (c==K_U) --udpos;
if (c==K_PGU) udpos-=nud;
if (udpos<0) udpos=0;
goto DWNGZ;
if (udpos>=nzeil) goto JBEEP;
if (c==K_D) ++udpos;
if (c==K_PGD) udpos+=nud;
if (udpos>=nzeil) { udpos=nzeil; goto KESC; }
DWNGZ:;
zi= GetZ(Zeile, udpos);
cup=Cup;
break;
if (cup>0) CursLR(-1), Cup=--cup;
continue;
if (cup<zi) CursLR(1), Cup=++cup;
continue;
cup=0;
//...
Warum? Weil du diesen Kram selbst gebastelt hast? In realen Programmen
ist man IMHO mit curses *erheblich* besser bedient. Und ein vollstaendiger
Eoingabe editor (wie ihn libreadline bietet) ist das bei weitem auch noch
nicht ...
Es ist ein vollständiger Kommandozeilen-Editor, etwas besser als DOSKEY.
Ich hatte mich in den 1990ern so 2-3 Tage mit curses beschäftigt.
Und ich habe mich danach nach einiger Überlegung gegen curses entschieden.
Nicht allumfassend gegen curses, sondern nur meine geplanten Projekte betreffend.

=================================================================================
char *
readline (const char *prompt);

COPYRIGHT
Readline is Copyright (C) 1989-2014 Free Software Foundation, Inc.

DESCRIPTION
readline will read a line from the terminal and return it, using prompt
as a prompt. If prompt is NULL or the empty string, no prompt is
issued. The line returned is allocated with malloc(3); the caller must
free it when finished. The line returned has the final newline
removed, so only the text of the line remains.

readline offers editing capabilities while the user is entering the
line. By default, the line editing commands are similar to those of
emacs. A vi-style line editing interface is also available.
=================================================================================

Es ist hier zu bemerken, welches Konzept hier vorliegt.
Für mich nicht/kaum gebrauchsfähig.

Was ich damals mindestens brauchte:

Einzeltastendruck-Bedienung
Einfüge- und Überschreib-Modus
Löschen, Springen HOME & END, Bewegen links & rechts
Automatisches Speichern jeder eingegebenen Zeile
Wieder hochholen & back jeder gespeicherten Zeile; Springen PGup,PGdown
Dabei die letzte Schreibposition speichern und verwenden

Meine Lösung ist einfacher und schneller bedienbar, dennoch voll ausreichend.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
http://www.schellong.de/c.htm http://www.schellong.de/c2x.htm http://www.schellong.de/c_padding_bits.htm
http://www.schellong.de/htm/bishmnk.htm http://www.schellong.de/htm/rpar.bish.html http://www.schellong.de/htm/sieger.bish.html
http://www.schellong.de/htm/audio_proj.htm http://www.schellong.de/htm/audio_unsinn.htm http://www.schellong.de/htm/tuner.htm
http://www.schellong.de/htm/string.htm http://www.schellong.de/htm/string.c.html http://www.schellong.de/htm/deutsche_bahn.htm
http://www.schellong.de/htm/schaltungen.htm http://www.schellong.de/htm/rand.htm http://www.schellong.de/htm/bsd.htm
Thomas Koenig
2022-05-08 20:44:19 UTC
Permalink
Post by wolfgang bauer (D)
Hallo
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss.
Wie andere schon geschrieben haben, geht das mit Standard-C nicht
genau so.

Was aber geht, ist einen Default-Wert einzustellen und den im
Zweifelsfall einfach nicht zu überschreiben, etwa so:

#include <stdio.h>

int main()
{
char buffer[80];
double a;
int rc;
a = 2.0;
fgets (buffer, sizeof buffer, stdin);
rc = sscanf (buffer, "%lf", &a);
if (rc != 1)
fprintf (stderr, "Warnung: Default-Wert verwendet!\n");

printf ("Wert ist jetzt: %f\n", a);
return 0;
}

oder eine Variation davon (Puffergröße, Fehlerbehandlung,
Rückgabewert von fgets, was passiert, wenn der Benutzer
fasdfasdfasdfa statt 1.2 eingibt, getline() stat fgets(),
falls man POSIX verwendet oder es selber implementiert, ...)

Mit scanf direkt geht das nicht, weil scanf auch über Zeilenenden
hinausliest, um einen Wert zu bekommen.
Helmut Schellong
2022-05-09 10:40:21 UTC
Permalink
Post by Thomas Koenig
Post by wolfgang bauer (D)
Hallo
Ich möchte eine Eingabe für scanf vorgeben, so das man in der
Konsole nur noch ohne weitere Eingabe die Returntaste drücken muss.
[...]
Post by Thomas Koenig
Mit scanf direkt geht das nicht, weil scanf auch über Zeilenenden
hinausliest, um einen Wert zu bekommen.
Von stdin her, oder mit sscanf?

Mit setvbuf() kann der Puffermodus geändert werden.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
Loading...