Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » std::cin <--> newline ?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
14.08.2003, 17:21 Uhr
Marzel



Ich habe das Problem, dass ich std::cin auslesen muss, jedoch dort kein newline am ende vorliegt, so dass ich mit getchar und div. anderen Methoden noch nicht auf den Inhalt zugreifen kann.

Die Lösung einer der folgenden Probleme würde mir reichen, jedoch weiss ich nicht wie das geht:

1. wie kann ich std::cin auslesen ohne dass Return gedrückt wurde. (kann man irgendwie definieren, nach welchem zeichen, die eingabe beendet sein soll (defaultmässig newline))

2. wie kann ich einen character in den Eingabestrom schreiben? Dann könnte ich einfach das newline-Zeichen selbst hinzufügen und hoffen, dass das klappt.

Jede andere Idee ist natürlich auch willkommen :-)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
14.08.2003, 18:04 Uhr
virtual
Sexiest Bit alive
(Operator)


ad 1:
bis ein zeichen bei cin ankommt, gibt es mehrere Layer. Wenn dein cin mit einem Medium verknüft ist, welches nicht großartig buffert, dann genügt es, cin auf unbuffered zu setzen. Da du aber vermuitlich von Tastatur liest, wird dir das nichts bringen, weil nämlich das Terminal die Zeichen für sich behält, bis ein Newline auftritt. Die Lösung ist damit nicht mit ANSI C++ lösbar, du musst Platformspezifische Dinge tun.

ad 2:
cin ist ein std::istream und läßt damit keine Schreiboperationen zu. In manchen Fällen mag es ein std::iostream sein, das ist aber nicht garantiert
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
14.08.2003, 18:12 Uhr
Marzel



um das problem näher zu spezifieren: std::cin ist der eingabestrom der tastatur, und daher std::istream.

Ich sende ein Request Cursor Position Escape Sequenz an das Terminal, das mir dann die Position in std::cin schreibt, jedoch ohne newline am ende.


C++:
    static std::string queryCursorPosition(int &row, int &col, std::ostream &src){
        std::string ret="";
        row=0;
        col=0;
        src<<"\x1B[6n";
        
        bool isRow=true;
        
        int k=getchar();
        if (k==27){
            while(k!='R'){
                k=getchar();
                if ((k!='[')&&(k!='R')&&(k!=';')){
                    if (isRow){
                        row=row*10+(k-48);
                        
                    } else {
                        col=col*10+(k-48);
                        
                    }
                }
                if (k==';'){
                    isRow=!isRow;
                }
                
            }
        }
        
        return ret;
    }



Bei der Zeile
int k=getchar();
wird aber leider bis zur Eingabe von Return gewartet.
Plattformabhängig ist es sowieso schon.... gehört dann wohl auch nicht ins Forum, oder?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
14.08.2003, 18:27 Uhr
0xdeadbeef
Gott
(Operator)


Quick and dirty wäre

C++:
//Windows
fflush(stdin);

//Unix
system("echo > /dev/stdin");


Das ist dann allerdings nicht portabel.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
14.08.2003, 20:31 Uhr
Marzel



...das funktioniert unter Windows??: www.eskimo.com/~scs/C-faq/q12.26.html

... die Unix Lösung funktioniert bei mir nicht wie gewünscht.

allerdings hab ich zu meinem 1.Problem

>> wie kann ich std::cin auslesen ohne dass Return gedrückt wurde. (kann man irgendwie definieren, >>nach welchem zeichen, die eingabe beendet sein soll (defaultmässig newline))

eine system-spezifische(denke ich) Lösung gefunden (linux):

code ursprünglich von:
www.h.eng.cam.ac.uk/help/tpl/languages/C++/FAQ.html#3
(hier im Forum ist übrigens ein Bug bei der Umwandlung der links:
www-h.eng.cam.ac.uk/help/tpl/languages/C++/FAQ.html#3
( www-h statt www.h ) )

..hab ich jedoch geändert da paar Fehler drin waren (warum auch immer)
Bei mir läuft es jetzt jedenfalls.

C++:
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <termios.h>

int tty_mode = 0;
struct termios orig_tty;
struct termios new_tty;

// Sets up terminal for one-char-at-a-time reads
void cbreak (void)
{
    if (tty_mode == 0)
    {
        tcgetattr(0, &orig_tty);
        tty_mode = 1;
        new_tty = orig_tty;
    }

    new_tty.c_lflag &= ~(ICANON | ECHO);
    new_tty.c_cc[VMIN] = 1;
    new_tty.c_cc[VTIME] = 0;
    tcsetattr(0, TCSANOW, &new_tty);
}


// Returns terminal to normal state after cbreak ()
void normal (void)
{
    if (tty_mode == 1)
    {
        tcsetattr(0, TCSANOW, &orig_tty);
        new_tty = orig_tty;
    }
}


// Checks keyboard buffer (stdin) and returns key
// pressed, or -1 for no key pressed

int keypress (void)
{
    static char keypressed;
    struct timeval waittime;
    int num_chars_read;
    fd_set mask;
    FD_SET(0, &mask);

    waittime.tv_sec = 0;
    waittime.tv_usec = 0;
    if (select (1, &mask, 0, 0, &waittime))
    {
        num_chars_read = read (0, &keypressed, 1);
        if (num_chars_read == 1)
            return ((int)keypressed);
    }

    return (-1);
}

int main()
{
char c;
normal();
  std::cout << "type a character (normal mode): ";
  std::cin >> c;
  cbreak();
  std::cout << "type a character (non-blocking): ";
  while ( keypress() == -1) {
     std::cout << "ok, I'll wait a second" << std::endl;
    sleep(1);
  }
  std::cout << "Thanks. Returning to normal behaviour" << std::endl;
  normal();
  return 0;
}



Dieser Post wurde am 14.08.2003 um 20:35 Uhr von Marzel editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
15.08.2003, 13:40 Uhr
0xdeadbeef
Gott
(Operator)


fflush(stdin) geht unter Windows, ja. Fand ich auch merkwürdig, aber es geht. Was Unix angeht - ich hatte sowas mal hier gepostet. Ich hab ein bisschen für dich gekramt, und hier ist der Code:

C++:
#include <stdio.h>
#include <termio.h>

void setTerminalBuffering(int new_state) {
    static struct termios stored_settings;
    static int old_state = 1;

    //Abbrechen, wenn nichts zu tun ist. Spart Rechenzeit.
    if(!old_state == !new_state) return;
    old_state = new_state;

    if(!new_state) {
        struct termios new_settings;
        tcgetattr(0,&stored_settings);
        new_settings = stored_settings;
        new_settings.c_lflag &= (~ICANON);
        new_settings.c_cc[VTIME] = 0;
        tcgetattr(0,&stored_settings);
        new_settings.c_cc[VMIN] = 1;
        tcsetattr(0,TCSANOW,&new_settings);
    } else {
        tcsetattr(0,TCSANOW,&stored_settings);
    }
}

int main() {
    setTerminalBuffering(0); //ab jetzt geht getchar() wie getch(), nur ohne ncurses
    printf("\n%c\n", getchar());
    setTerminalBuffering(1); //jetzt will getchar() wieder ein return haben
    return 0;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 15.08.2003 um 13:45 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
15.08.2003, 13:43 Uhr
0xdeadbeef
Gott
(Operator)


Wenn Rechenzeit keine Rolle spielt, kannst du dann sowas machen;

C++:
int getch() {
    char c;
    setTerminalBuffering(0);
    c = getchar();
    setTerminalBuffering(1);
    return c;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 15.08.2003 um 13:45 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: