reading formatted strings: readf("%s", &stringvar)

Ali Çehreli acehreli at yahoo.com
Mon Mar 26 10:34:36 PDT 2012


On 03/26/2012 04:55 AM, Tyro[17] wrote:

 >> > void main(string[] args)
 >> > {
 >> > string s1;
 >> > double d;
 >> > string s2;
 >> >
 >> > writeln("Enter a @ terminated string (multiline ok):");
 >> > readf(" %s@", &s1);
 >> > auto arr = s1.split();
 >> >
 >> > if (!stdin.eof()) {

Ah! That's one of the problems. stdin has no idea whether there are more 
characters available. eof() being true is not dependable unless an 
attempt to read a character is made and failed. This is the case in C 
and C++ as well.

 >> > writeln("The stream is not empty.");
 >> > } else {
 >> > writeln("The stream is empty.");
 >> > }
 >> > writeln("Enter another string (terminated with
 >> cntrl-d|ctrl-z):");
 >>
 >> I am not sure about the cntrl-d|ctrl-z part though. Since it
 >> terminates the input, the program should not be able to read any more
 >> characters.

I would like to repeat: ending the stream is not a solution because you 
want to read more data.

 >>
 >> > readf(" %s", &s2); // No matter how many read attempts

That's the actual problem, and ironically is already known to you. :) 
Use a \n at the end of that format string.

 >>
 >> I advise reading string by readln(). You can call chomp() to get rid
 >> of whitespace around it:
 >>
 >> while (s2.length == 0) {
 >> s2 = chomp(readln());
 >> }
 >
 > You can achieve the same with:
 >
 > readf(" %s\n", &s2);

Thank you. However, that method does not remove trailing whitespace.

 > My goal however, is not to read one line of information. Rather, it is to
 > read multiple lines of information from standard input. I get close to
 > being able to do so if i don't including "\n" as a part of my format 
string
 > or if I changing your suggestion to
 >
 > while (!stdin.eol()) {
 > s2 = chomp(readln());
 > }
 >
 > but again I run into the predicament was before, a need to close the
 > the stream with Ctrl-D/Ctrl-Z.

If I understand you correctly, the following program works for me:

import std.stdio;
import std.string;

void main(string[] args)
{
     string s1;
     double d;
     string s2;

     writeln("Enter a @ terminated string (multiline ok):");
     readf(" %s@", &s1);
     auto arr = s1.split();

     writeln("Enter a line of string:");
     readf(" %s\n", &s2);

     writeln("Enter a decimal value:");
     readf(" %s", &d);

     writeln("d = ", d);
     writeln("arr = ", arr);
     writeln("s = ", s2);
}

Ali



More information about the Digitalmars-d mailing list