Своеобразное поведение writef / writefln? - PullRequest
3 голосов
/ 03 января 2012

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

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

Проходя базовые уроки dsource.org , я читал раздел Wait , когда заметилчто если вы используете 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 ]

6 голосов
/ 03 января 2012

Используйте stdout.flush(); после любых звонков на write или writef.Эти последние вызовы не очищают буфер, поэтому вы видите такое поведение.Кстати, 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");
4 голосов
/ 03 января 2012

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

...