Своеобразное поведение 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
всегда сбрасывает вывод. Весь текст после последней новой строки буферизируется до конца программы.