Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
October 29, 2014 readln with buffer fails | ||||
---|---|---|---|---|
| ||||
I have this simple code: int main() { import std.stdio; char[4096] Input; readln(Input); //readln!(char)(Input); // also fails return 0; } I get these messages during compilation: test.d(39): Error: template std.stdio.readln cannot deduce function from argument types !()(char[4096]), candidates are: src\phobos\std\stdio.d(2818): std.stdio.readln(S = string)(dchar terminator = '\x0a') if (isSomeString!S) src\phobos\std\stdio.d(2851): std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum)) src\phobos\std\stdio.d(2858): std.stdio.readln(C, R)(ref C[] buf, R terminator) if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && isBidirectionalRange!R && is(typeof(terminator.front == (dchar).init))) Now, I'm used to 'buffer' meaning one thing, but here it seems that buffer means something more akin to a 'sink' object, or a forced dynamic array type? Is there some way I can avoid dynamic allocations? Thanks! |
October 29, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to dcrepid | You need to take a slice of the buffer: char[] buf = Input[]; readln(buf); // line now in buf The reason for this is because you need to know where the string ends. If you just passed in Input, how would you know how long the line read was? |
October 29, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to dcrepid | On Wednesday, 29 October 2014 at 21:14:17 UTC, dcrepid wrote:
> I have this simple code:
> int main()
> {
> import std.stdio;
> char[4096] Input;
> readln(Input);
> //readln!(char)(Input); // also fails
> return 0;
> }
>
> I get these messages during compilation:
> test.d(39): Error: template std.stdio.readln cannot deduce function from
> argument types !()(char[4096]), candidates are:
> src\phobos\std\stdio.d(2818):
> std.stdio.readln(S = string)(dchar terminator = '\x0a') if (isSomeString!S)
> src\phobos\std\stdio.d(2851):
> std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
> src\phobos\std\stdio.d(2858):
> std.stdio.readln(C, R)(ref C[] buf, R terminator) if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && isBidirectionalRange!R && is(typeof(terminator.front == (dchar).init)))
>
> Now, I'm used to 'buffer' meaning one thing, but here it seems that buffer means something more akin to a 'sink' object, or a forced dynamic array type? Is there some way I can avoid dynamic allocations?
>
> Thanks!
try this instead
------
module runnable;
import std.stdio;
void main(string args[])
{
char[] Input;
Input.length = 4096;
readln(Input);
}
------
Your original sample does not compile because `char[4096]` is a
static array and does not verifies the redln() template constraints,
e.g input range, forward range etc.
Another option would be to slice Input:
----
readln(Input[0..$-1]);
----
|
October 29, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to dcrepid Attachments: | On Wed, 29 Oct 2014 21:14:13 +0000 dcrepid via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > Now, I'm used to 'buffer' meaning one thing, but here it seems that buffer means something more akin to a 'sink' object, or a forced dynamic array type? Is there some way I can avoid dynamic allocations? take a slice of your buffer: `Input[]`. slices aren't doing allocations, they just keeping pointer to data and data length together. |
October 29, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | On Wednesday, 29 October 2014 at 21:19:25 UTC, Peter Alexander wrote:
> You need to take a slice of the buffer:
>
> char[] buf = Input[];
> readln(buf);
> // line now in buf
>
> The reason for this is because you need to know where the string ends. If you just passed in Input, how would you know how long the line read was?
Thanks, that solves the problem. I guess what confuses me is that Input isn't a slice, or at least not implicitly convertible to one.
Also, I've tried using Input[] directly at the callsite but apparently that would be an rValue, and D doesn't do rValues yet.
So here's a simple solution to reading a line using a fixed stack array:
char[4096] Input;
char[] InputSlice; // actual slice of input'd text (instead of full 4K)
size_t NumChars;
while (NumChars == 0)
{
// readln(buf) requires a slice. Input isn't converted to one,
// and readln() requires an rvalue for a buffer:
char[] buf = Input[];
NumChars = readln(buf);
// Set InputSlice to range of text that was input, minus linefeed:
InputSlice = chomp(buf[0 .. NumChars]);
// Empty line?
if (InputSlice == "")
NumChars = 0;
}
Thanks all for your help
|
October 29, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to dcrepid | err, I meant rvalue *reference* above |
October 29, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to dcrepid | lol, if only I could edit my posts. The comment preceding the readln() call was wrong too. This is what I have now: // readln(buf) requires a slice *Reference*. // rvalue references aren't supported by D, so readln(Input[]) fails |
October 29, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to dcrepid | On Wed, 29 Oct 2014 23:10:10 +0000, dcrepid wrote:
> On Wednesday, 29 October 2014 at 21:19:25 UTC, Peter Alexander wrote:
>> You need to take a slice of the buffer:
>>
>> char[] buf = Input[];
>> readln(buf);
>> // line now in buf
>>
>> The reason for this is because you need to know where the string ends. If you just passed in Input, how would you know how long the line read was?
>
> Thanks, that solves the problem. I guess what confuses me is that Input isn't a slice, or at least not implicitly convertible to one.
>
> Also, I've tried using Input[] directly at the callsite but apparently that would be an rValue, and D doesn't do rValues yet.
Part of what readln does is *modify* the slice itself, not just the
pointed-to
characters. In particular it alters the length member so that you know
how much
input was actually read. This is also why the rvalue reference shouldn't
work.
Remember, D chose not to repeat C's mistake of relying on null
terminators.
|
October 30, 2014 Re: readln with buffer fails | ||||
---|---|---|---|---|
| ||||
Posted in reply to Justin Whear | On Wednesday, 29 October 2014 at 23:28:07 UTC, Justin Whear wrote:
> Part of what readln does is *modify* the slice itself, not just the
> pointed-to
> characters. In particular it alters the length member so that you know
> how much
> input was actually read. This is also why the rvalue reference shouldn't
> work.
> Remember, D chose not to repeat C's mistake of relying on null
> terminators.
Nice, thanks for that. I wasn't aware the .length member was changed, but I just verified it myself by surrounding the call with some debug output. Sure enough, its length is 4096 before the call, and a different length after (depending on what was input).
|
Copyright © 1999-2021 by the D Language Foundation