www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - read single characters from stdin

reply Thomas Koch <thomas koch.ro> writes:
Hi,

to learn D, I'd like to write a simple type trainer. It should write a line 
to stdout and then read single characters from stdin and only accept the 
correct characters

How can I read single characters?

A similar question has been asked before without a working answer:
http://forum.dlang.org/thread/jl79f7$2083$1 digitalmars.com

But I can't beliebe that there isn't a simple solution in D for this 
problem...

Regards, Thomas Koch
Sep 26 2012
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 26 September 2012 at 17:51:03 UTC, Thomas Koch 
wrote:
 How can I read single characters?

The way I'd do it is with the C call fgetc(stdin). You can do it in D the same way if you import core.stdc.stdio; But, if you are on Linux, it isn't going to be that simple. The Linux terminal/operating system will buffer input, not sending any data to you until the user presses enter. You'll probably want to use a library like ncurses on linux... you can do without too, turning on raw mode to the terminal I think, but I don't remember how to do it right now. Are you on Linux or Windows? (I'm pretty sure it just works on windows but it's been a while since I've done an app like this.)
Sep 26 2012
prev sibling next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 09/26/2012 10:51 AM, Thomas Koch wrote:
 Hi,

 to learn D, I'd like to write a simple type trainer. It should write 

 to stdout and then read single characters from stdin and only accept the
 correct characters

 How can I read single characters?

 A similar question has been asked before without a working answer:
 http://forum.dlang.org/thread/jl79f7$2083$1 digitalmars.com

Considering that stdin is a char stream and that there is no concept of a keyboard or a monitor in D (nor in C and nor in C++), I stand by my solution from that thread: :) import std.stdio; void main() { while (!stdin.eof) { char code; readf("%s", &code); writefln("%u", code); } } Just remember that char is a UTF-8 code unit.
 But I can't beliebe that there isn't a simple solution in D for this
 problem...

This thread may have some answers: http://forum.dlang.org/thread/im8cnf$ioe$1 digitalmars.com?page=1 Ali
Sep 26 2012
parent Thomas Koch <thomas koch.ro> writes:
Ali Çehreli wrote:
 Considering that stdin is a char stream and that there is no concept of
 a keyboard or a monitor in D (nor in C and nor in C++), I stand by my
 solution from that thread: :)

press enter. Regards, Thomas Koch
Sep 28 2012
prev sibling next sibling parent reply "nazriel" <spam dzfl.pl> writes:
On Wednesday, 26 September 2012 at 17:51:03 UTC, Thomas Koch 
wrote:
 Hi,

 to learn D, I'd like to write a simple type trainer. It should 
 write a line
 to stdout and then read single characters from stdin and only 
 accept the
 correct characters

 How can I read single characters?

 A similar question has been asked before without a working 
 answer:
 http://forum.dlang.org/thread/jl79f7$2083$1 digitalmars.com

 But I can't beliebe that there isn't a simple solution in D for 
 this
 problem...

 Regards, Thomas Koch

http://dpaste.dzfl.pl/eb1387cc ;-)
Sep 26 2012
parent Thomas Koch <thomas koch.ro> writes:
nazriel wrote:
 http://dpaste.dzfl.pl/eb1387cc

I extended it: import core.sys.posix.termios; import core.stdc.stdio; char getch() { int ch; termios oldt; termios newt; tcgetattr(0, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(0, TCSANOW, &newt); ch = getchar(); tcsetattr(0, TCSANOW, &oldt); return cast(char) ch; } import std.utf; char readChar() { char[4] buffer; buffer[0] = getch(); auto len = stride(buffer,0); foreach (i ; 1 .. len) buffer[i] = getch(); size_t i; return cast(char) decode(buffer, i); }
Sep 28 2012
prev sibling next sibling parent "nazriel" <spam dzfl.pl> writes:
On Friday, 28 September 2012 at 09:45:30 UTC, Thomas Koch wrote:
 nazriel wrote:
 http://dpaste.dzfl.pl/eb1387cc

characters, so I extended it:

Nice, I didn't need multibyte support as I was using it mainly for getting keycode
 import core.sys.posix.termios;
 import core.stdc.stdio;

 char getch()
 {
         int ch;
         termios oldt;
         termios newt;

         tcgetattr(0, &oldt);
         newt = oldt;
         newt.c_lflag &= ~(ICANON | ECHO);
         tcsetattr(0, TCSANOW, &newt);
         ch = getchar();
         tcsetattr(0, TCSANOW, &oldt);

         return cast(char) ch;
 }

 import std.utf;

 char readChar()
 {
     char[4] buffer;

     buffer[0] = getch();
     auto len = stride(buffer,0);

     foreach (i ; 1 .. len)
         buffer[i] = getch();

     size_t i;
     return cast(char) decode(buffer, i);
 }

I think it should return dchar then, and cast(char) should be dropped otherwise you will lose visual representation of anything that is bigger than 8bits
Sep 28 2012
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-09-26 19:51, Thomas Koch wrote:
 Hi,

 to learn D, I'd like to write a simple type trainer. It should write a line
 to stdout and then read single characters from stdin and only accept the
 correct characters

 How can I read single characters?

 A similar question has been asked before without a working answer:
 http://forum.dlang.org/thread/jl79f7$2083$1 digitalmars.com

This works for me on Mac OS X: http://forum.dlang.org/thread/jl79f7$2083$1 digitalmars.com?page=2#post-jlhn4d:241a5v:241:40digitalmars.com -- /Jacob Carlborg
Sep 28 2012
prev sibling parent 1100110 <0b1100110 gmail.com> writes:
On Wed, 26 Sep 2012 13:06:03 -0500, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Wednesday, 26 September 2012 at 17:51:03 UTC, Thomas Koch wrote:
 How can I read single characters?

The way I'd do it is with the C call fgetc(stdin). You can do it in D the same way if you import core.stdc.stdio; But, if you are on Linux, it isn't going to be that simple. The Linux terminal/operating system will buffer input, not sending any data to you until the user presses enter. You'll probably want to use a library like ncurses on linux... you can do without too, turning on raw mode to the terminal I think, but I don't remember how to do it right now. Are you on Linux or Windows? (I'm pretty sure it just works on windows but it's been a while since I've done an app like this.)

ncurses will do it with getch(). pdpurses should have the same function. You will most likely still have to ncurses setup and teardown though. shrug.
Sep 28 2012