Search code examples
d

Unwanted empty strings when reading input from stdio


Just making exercise with simple calculator. I've tried to run ahead and wraped it inside do-while loop. Then I've got a strange behaviour - catchin empty string on every new loop. One can see that at case "" code part.

So the question - what is going on and how to deal with it?

One can see my humble attempts to fix it on commented lines in the code:

import std.stdio;
import std.string;

void main() {

    writefln("---  Welcome to calculatro %s ---", " ");

    int exit = 0;

    do {


        string op;
        double first;
        double second;

        writeln("enter operator :");
        op = chomp(readln());
        writeln("operator :",op,":");
        //readf(" %s/n", &op);


        switch (op) {

        case "add", "+":
            writeln("enter two values :");
            //readf(" %s %s", &first, &second);
            readf(" %s", &first);
            readf(" %s", &second);
            writefln("%s+%s=%s", first, second, first+second);
            //writeln(first+second);   
            break;

        case "minus", "-", "substract":      
            writeln("enter two values :");
            readf(" %s %s", &first, &second);
            writefln("%s+%s=%s", first, second, first-second);
            break;        

        case "exit":
            exit = 1;
            break;

        case "":
            writeln("empty op");
            break;

        default:
            writefln("i dont know op!"~op);
            //writefln("%(%s%)", op);
            //writefln("%s", op);
            //throw new Exception(format("Unknown operation: %s", op));
            break;
        }    
    } while (exit == 0);

        writeln("good bye!");

}

Solution

  • Consider a run of 'calculatro':

    ---  Welcome to calculatro   ---
    enter operator :
    +
    operator :+:
    enter two values :
    4 5
    4+5=9
    enter operator :
    operator ::
    empty op
    enter operator :
    
    1. The user enters an operator, leaving '+\n' on stdio
    2. You use readln to consume all of stdio
    3. The user enters '4 5\n' as operands
    4. You use readf to consume '4 5', leaving '\n' on stdio
    5. The next loop, readln reads the next line from stdio
    6. There is already a line on stdio, consisting only of the '\n' left from before
    7. Because readln was able to read a whole line, the user is not prompted from input
    8. chomp removes the '\n', leaving you with an empty string

    A quick fix here is to call readln after you get your operands to consume the trailing newline. For example:

        case "add", "+":
            writeln("enter two values :");
            //readf(" %s %s", &first, &second);
            readf(" %s", &first);
            readf(" %s", &second);
            readln(); // <----- read trailing newline
            writefln("%s+%s=%s", first, second, first+second);
            //writeln(first+second);   
            break;