www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How does buffering actually work?

reply Cleverson Casarin Uliana <clul mm.st> writes:
Hi all, this may be a really newbie question but I'm not really used to 
medium/low level stuff like this. I've actually done the same in Python, 
and it just works...

Supose I want my program to print some content on a given line, lets say 
"First name: value1", then it should sit down and wait for me to press 
Enter, then print "Second name: value2", then sit down again, and so on. 
I've tried to do that the following way:

import std.stdio;
void myFunc(string name, double value) {
write(name, value);
string buf;
readf(" %s", buf);
}

then I just call multiple times:

void main() {
myFunc("First name: ", value1);
myFunc("Second name: ", value2);
(...)
}

It works almost perfectly, except that it doesn't wait for my first 
Enter after printing "First name: value1". Rather, it prints both "First 
name: value1" and "First name: value2" together on the same line, then 
it starts to behave as expected, e.g. printing one line at a time and 
waiting for me to press Enter.

I experimented substituting readf for readln, but then it doesn't 
recognize my Enter presses and hangs on.

What is a more suitable aproach to this problem please?

Thanks,
Cleverson
Feb 28
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 02/28/2019 01:17 PM, Cleverson Casarin Uliana wrote:

 I experimented substituting readf for readln, but then it doesn't
 recognize my Enter presses and hangs on.

 What is a more suitable aproach to this problem please?
readln and strip works, and formattedRead can be useful as well. I have an example here: http://ddili.org/ders/d.en/strings.html#ix_strings.readln import std.stdio; import std.string; void main() { char[] name; write("What is your name? "); readln(name); name = strip(name); writeln("Hello ", name, "!"); } Ali
Feb 28
prev sibling parent reply sarn <sarn theartofmachinery.com> writes:
On Thursday, 28 February 2019 at 21:17:23 UTC, Cleverson Casarin 
Uliana wrote:
 It works almost perfectly, except that it doesn't wait for my 
 first Enter after printing "First name: value1". Rather, it 
 prints both "First name: value1" and "First name: value2" 
 together on the same line, then it starts to behave as 
 expected, e.g. printing one line at a time and waiting for me 
 to press Enter.
Perhaps that happened with some other variation of the code. The code you wrote shouldn't work like that (it doesn't for me when I tried, at least). Ali has some good answers for fixing your code. (readf("\n") also works, BTW.) Hopefully this helps with the "How does buffering actually work?" question: D uses the system's standard C library for IO, like most programming languages do, so IO buffering isn't fundamentally different (but some high-level functions might have different behaviour). The standard C library provides buffered IO for input and output. By default terminal IO is line-buffered (not sure if that's all systems), so you might see delays up until a newline, but line-by-line IO won't notice the buffering. What happens here? write() read() write() read() The first write goes to the output buffer. If the buffer ever gets full (or has a newline in the case of line buffering), the data gets flushed to the real output. At the read, it's possible there's still some data in the output buffer that's not flushed. If needed, you can explicitly call flush() to make sure there isn't. If there happens to already be data in the read buffer, read() will take as much as it needs to. If there isn't enough, then real input will happen, and the call will block until data comes in. The real read will ask for a chunk of data, which will often be more than the read() call needs. The remainder gets put into the buffer (that's what it's for). (The kernel and libc actually both have IO buffers.) In any case, the second write won't happen until the read has finished. Rinse and repeat for the remaining lines.
Feb 28
parent reply Cleverson Casarin Uliana <clul mm.st> writes:
Hi, thank you both Ali and Sarn.

How am I suposed to use the flush function? I've found it in the 
std.stdio reference, buth calling it in my code gives "undefined 
identifier", even though std.stdio is imported.

Greetings,
Cleverson
Feb 28
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 28 February 2019 at 23:07:44 UTC, Cleverson Casarin 
Uliana wrote:
 How am I suposed to use the flush function? I've found it in 
 the std.stdio reference, buth calling it in my code gives 
 "undefined identifier", even though std.stdio is imported.
try stdout.flush(); flush is a member function of the file object.
Feb 28
parent Cleverson Casarin Uliana <clul mm.st> writes:
Thanks Adam, I'll test it later.

Cheers
Cleverson
Feb 28