readf with strings

Kai Meyer kai at unixlords.com
Wed Jun 22 12:01:13 PDT 2011


On 06/22/2011 09:30 AM, Ali Çehreli wrote:
> On Wed, 22 Jun 2011 14:57:57 +0000, GreatEmerald wrote:
>
>> This should be a very elementary question. How do you get a string off
>> stdin? Or an integer, or a boolean, for that matter? If I use this:
>>
>>    float MyFloat;
>>    string MyString;
>>    readf("%f",&MyFloat);
>>    writeln(MyFloat);
>>    readf("%s",&MyString);
>>    writeln(MyString);
>>
>> I get the float printed correctly, but when it asks to input the string,
>> whatever I input gets ignored - I can't reach the writeln part in any
>> way and I have to forcibly close the program. The same thing is with
>> ints - if I enter an int, it acts as if I didn't enter anything at all.
>> But floats work fine for some reason. Any thoughts about what is
>> happening there?
>>
>> I'm using openSUSE 11.4 and DMD 2.053.
>
> Reading from an input stream is sometimes confusing.
>
> Things to remember:
>
> - Use %s for any type unless there is reason not to
>
> - The line terminator from the previous entry is still in the input. (You
> may call readf(" ") to flush those white space characters. (I've just
> discovered this.))
>
> - string can hold any character including space and the line terminator.
> That's why pressing the Enter doesn't terminate reading a string.
>
> - Use a space character before any format specifier to ignore zero or
> more whitespace characters before the previous input: " %s".
>
> - To read a string (actually a line), use chomp(readln())
>
> - I don't know whether this is intended and I don't think that we should
> routinely use this: The EOF (Ctrl-D on Unix consoles, Ctrl-Z on Windows)
> terminates reading the string but strangely not the entire input.
>
> import std.stdio;
> import std.string;
>
> void main()
> {
>      float MyFloat;
>      readf(" %s",&MyFloat);
>      writeln(MyFloat);
>
>      readf(" ");
>
>      string MyString = chomp(readln());
>      writeln(MyString);
> }
>
> Ali

Remember that readf is reading characters, and converting them to types 
for you. I've just gotten in the habbit of reading in the string, and 
then parsing the string on my own. Readf doesn't grant me anything 
special that I can't do on my own. It's easy enough to do something like 
this:

[kai.meyer at kai-rhel6 sandbox]$ cat d_read.d
import std.stdio;
import std.string;
import std.conv;

void main()
{
     string[] buffer;
     int a;
     float b;
     string c;
     buffer = chomp(readln()).split(" ");
     a = to!(int)(buffer[0]);
     b = to!(float)(buffer[1]);
     c = buffer[2..$].join(" ");
     writef("Read in: '%d' '%f' '%s'\n", a, b, c);
}


If I type:
1 1.3 this is a string

On the command line after the execution, I get this back:
Read in: '1' '1.300000' 'this is a string'

It's not very stream-ish, because readln breaks on a new line. You could 
call the "buffer = chomp..." line again if (buffer.length == 0) before 
you attempt another conversion.



More information about the Digitalmars-d-learn mailing list