为什么 SDL2 在最后一个 printf 之前显示对话框消息?很有意思

Why does SDL2 display the dialog messages before the last printf? Very interesting

我不明白为什么在 "printf" 语句之前显示对话框消息。

如果我在 "printf" 中添加一个 '\n',它会正常运行,但如果没有它,对话框最终会显示在 "printf".

之前

这里是测试程序:

/* Build: gcc -o test `sdl2-config --libs --cflags` test.c */

#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>

void MessageBox(void);
void clean(void);

int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_EVERYTHING);
    atexit(clean);
    SDL_DisplayMode mode;
    int id = 0;
    SDL_GetCurrentDisplayMode(id, &mode);
    char smode[20];
    sprintf(smode, "%ix%i@%iHz", mode.h, mode.w, mode.refresh_rate);
    printf("%s", smode);

    MessageBox();

    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
            "Missing file",
            "File is missing. Please reinstall the program.",
            NULL
            );
    return(0);
}

void MessageBox() {
    const SDL_MessageBoxButtonData buttons[] ={ /* .flags, .buttonid, .text */
        {0, 0, "no"},
        {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "yes" },
        { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "cancel" },
        };

    const SDL_MessageBoxColorScheme colorScheme = { /* .colors (.r, .g, .b) */
        {   /* [SDL_MESSAGEBOX_COLOR_BACKGROUND] */
            { 0, 0, 0 },
                /* [SDL_MESSAGEBOX_COLOR_TEXT] */
            { 0, 255, 0 },
                /* [SDL_MESSAGEBOX_COLOR_BUTTON_BORDER] */
            { 255, 255, 255 },
                /* [SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND] */
            { 0, 0, 0 },
                /* [SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED] */
            { 255, 0, 255 }
        }
    };
    const SDL_MessageBoxData messageboxdata = {
        SDL_MESSAGEBOX_INFORMATION, /* .flags */
        NULL,                       /* .window */
        "example message box",      /* .title */
        "select a button",          /* .message */
        SDL_arraysize(buttons),     /* .numbuttons */
        buttons,                    /* .buttons */
        &colorScheme                /* .colorScheme */
    };
    int buttonid;
    if(SDL_ShowMessageBox(&messageboxdata, &buttonid) < 0) {
        SDL_Log("error displaying message box");
    }
    if(buttonid == -1) {
        SDL_Log("no selection");
    } else {
        SDL_Log("selection was %s", buttons[buttonid].text);
    }
}

void clean() {
    SDL_Quit();
}

看似混合输出顺序的原因是因为在 C 中,stdout 是内部缓冲的。

只有几种方法可以将标准输出缓冲区实际刷新到终端。

  1. a fprintf( stdout,... 格式字符串以 '\n' 结尾
  2. printf() 的类似格式字符串注意事项
  3. 通过 %s 输出的字符串项包含 \n
  4. 函数fflush( stdout )被执行
  5. 程序尝试从 stdin
  6. 输入任何内容
  7. 程序退出
  8. 缓冲区已完全填满
  9. 在程序开始时调用 setbuf() 函数,将 stdout 缓冲区设置为长度 0
  10. 调用了puts()函数。
  11. 调用 putc() 函数时使用字符参数 '\n'