Своеобразное поведение writef/writefln?

Итак, я смотрю на D около 15 минут, поэтому неудивительно, что у меня есть вопросы, но что-то странное происходит со мной.

Я установил D отсюда и Visual D отсюда, и я запускаю все в Visual Studio 2010 Professional. Примеры D компилируются и запускаются, и отладчик работает нормально.

Просматривая основные учебники dsource.org, я читал раздел " Ожидание ", когда заметил, что если вы используете writef вместо writefln затем печатается последняя строка вывода после паузы.

Вот пример кода:

import std.c.stdio; /* for getch() */
import std.process; /* for system() */
import std.stdio; /* for writefln */

void main() { 
    writefln("Press a key (using 'std.c.stdio.getch();' to wait) . . .");
    getch();

    writefln("Waiting again\n(using 'system(\"pause\");'):");
    system("pause");
}

А вот мое, обратите внимание, единственное изменение writefln в writef

import std.c.stdio; /* for getch() */
import std.process; /* for system() */
import std.stdio; /* for writefln */

void main() { 
    writef("Press a key (using 'std.c.stdio.getch();' to wait) . . .");
    getch();

    writef("Waiting again\n(using 'system(\"pause\");'):");
    system("pause");
}

С writef программа ничего не отобразит на экране, остановитесь на getchзатем, когда я нажимаю клавишу, я вижу приглашение:

Press a key (using 'std.c.stdio.getch();' to wait) . . .Waiting again
Press any key to continue . . . 

но НЕ "(используя 'system("pause");'):". Заключение в скобки появляется после того, как я нажимаю клавишу, чтобы пройти через команду "пауза" в консоли. Если я использую writefln он печатает, ждет, печатает обе строки, затем снова ждет, как вы ожидаете.

Чем объясняется такое поведение?

2 ответа

Решение

Использование stdout.flush(); после любых звонков write или же writef, Эти последние вызовы не очищают буфер, поэтому вы видите такое поведение. Btw getch не в std.c.stdio (по крайней мере, не в D2?), он находится в библиотеке CRT DMC (SNN.lib), и для правильного использования вы должны будете создать его как extern (C) int getch();:

extern (C) int getch();
import std.process; /* for system() */
import std.stdio; /* for writefln */

void main() { 
    writef("Press a key (using 'std.c.stdio.getch();' to wait) . . .");
    stdout.flush();
    getch();

    writef("Waiting again\n(using 'system(\"pause\");'):");
    stdout.flush();
    system("pause");
}

Но это не является кросс-платформенной совместимостью из-за getch(), Если вы хотите использовать более удобное средство ввода данных пользователем, вы можете проверить библиотеку Джесси cmdln: https://github.com/he-the-great/JPDLibs/tree/cmdln. У него довольно классный интерфейс:

auto num = require!(int, "a > 0 && a <= 10")("Enter a number from 1 to 10");

Эта тема на gmane.comp.lang.d.learn кажется, указывает на то, что writef сбрасывает вывод, только когда встречает перевод строки. поскольку writefln это простой вызов writef с новой строкой, writefln всегда сбрасывает вывод. Весь текст после последней новой строки буферизируется до конца программы.

Другие вопросы по тегам