Не могу выполнить сброс стандартного вывода C++

Я новичок в C++ и подумывал о запуске приложения, которое интегрирует lua в качестве языка расширения. Я скопировал откуда-то простой код REPL, приведенный ниже, и слегка адаптировал его к C++, но «в конце» и «fprintf в конце» не появляются, когда я запускаю в режиме выпуска после завершения ввода с помощью Ctrl+D, несмотря на мои множественные варианты вызова сброса, но появляются, когда я запускаю в режиме отладки, даже без каких-либо точек останова. Это довольно деморализующее начало того, что должно быть легкой частью; что мне не хватает? Я работаю на MacO в CLion с помощью набора инструментов clang, предоставляемого XCode, если это имеет значение.

#include <iostream>

extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}

int main() {
    std::cout << "at beginning" << std::endl;
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    for (std::string line; std::getline(std::cin, line);) {
        const char *cLine = line.c_str();
        int error = luaL_loadstring(L, cLine) || lua_pcall(L, 0, 0, 0);
        if (error) {
            const char *luaOut = lua_tostring(L, -1);
            std::cerr << luaOut << std::endl;
            lua_pop(L, 1);
        } else {
            std::cout << "output above a result of evaluating: ["
                      << line
                      << "]"
                      << std::endl;
        }
    }
    lua_close(L);
    std::cout << "at end" << std::endl;
    fprintf(stdout, "fprintf at end\n");
    std::flush(std::cout);
    std::cout.flush();
    fflush(stdout);
    fflush(NULL);
    return 0;
}

пример сеанса ниже:

at beginning
print(2 ** 3)
[string "print(2 ** 3)"]:1: unexpected symbol near '*'
print(2 ^ 3)
8.0
output above a result of evaluating: [print(2 ^ 3)]
print("hope this works, too")
hope this works, too
output above a result of evaluating: [print("hope this works, too")]
^D

Обновлять

Если я закомментирую цикл, операторы std::cout в конце будут работать как положено. Если я закомментирую тело цикла, но оставлю оператор for нетронутым, операторы std::cout после цикла не будут работать.

Второе обновление

Запустив терминал и увидев, что все работает, а также прочитав комментарии ниже, кажется, что проблема не в коде C++, а в CLion. Я добавляю тег CLion. Если я не смогу найти решение этой очень тревожной проблемы, я откажусь от CLion, что меня разочаровывает, поскольку мне очень нравятся все остальные IDE JetBrains.

Добавьте больше вывода std::cout внутри цикла. Выведите значения line, cLine и error. Добавьте кавычки вокруг вывода строки, чтобы увидеть, есть ли неожиданные пробелы.

Some programmer dude 02.05.2024 13:20

Если программа не перестает работать при нажатии ctrl-d, то где она тратит свое время? Прикрепите к нему отладчик и сломайте.

Botje 02.05.2024 13:22

Придерживайтесь ввода-вывода C++, избегайте функций f*. Если первый смыв (<< std::endl;) не сработал, добавление еще четырех смывов не поможет.

molbdnilo 02.05.2024 13:22

Сработает ли это, если удалить все, что связано с Lua?

molbdnilo 02.05.2024 13:23

По совету @Someprogrammerdude я добавил выходные данные внутри цикла. В исходном посте я должен был ясно дать понять, что проблема не в Lua — он оценивает и печатает результаты, которые я ожидал.

SourceSimian 02.05.2024 13:41

@molbdnilo Да, это работает, когда я удаляю lua-включения и код Lua, так что остаются только вызовы std::cout плюс std::cout.flush()

SourceSimian 02.05.2024 13:44

@Botje В том-то и дело: программа останавливается, когда я нажимаю Ctrl+D, и, насколько я могу судить, весь код после выполнения цикла просто ничего не выводит, за исключением случаев, когда я запускаю в режиме отладки, даже без каких-либо точек останова. Это похоже на принцип неопределенности Гейзенберга: добавление отладчика и наблюдение за происходящим приводит к исправлению всего.

SourceSimian 02.05.2024 13:47

Не могу воспроизвести это на своем Mac. Я создал ваш код с помощью простого g++, и он всегда печатает для меня сообщения «в конце».

Botje 02.05.2024 13:57

Ты бежишь изнутри Клиона? Вы пробовали запустить его самостоятельно в независимом терминале? В прошлом у Clion были проблемы с фактическим сбросом вывода при запуске изнутри Clion.

Some programmer dude 02.05.2024 14:10

@Someprogrammerdude Да, я запускал это из CLion. Когда я запускаю его из терминала, я получаю нормальный результат.

SourceSimian 02.05.2024 14:18

@SourceSimian Так что я бы просто назвал эту штуку CLion «мусором» - или, может быть, она не поддерживает Ctrl-D или использует что-то еще для обозначения EOF.

Christian Stieber 02.05.2024 14:59

@ChristianStieber Ctrl+D работает. Он закрывает ввод и завершает программу с кодом выхода 0; Похоже, проблема в том, что CLion неправильно обрабатывает выходные данные программы. Проведя небольшое исследование, выяснилось, что это старая и постоянная проблема: youtrack.jetbrains.com/issue/CPP-5704

SourceSimian 02.05.2024 16:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
12
109
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оказывается, это не было проблемой кода ни на одной итерации. Проблема в том, что в CLion есть старая и не исправленная ошибка:

https://youtrack.jetbrains.com/issue/CPP-5704

Отключение run.processes.with.ptty дало мне ожидаемый результат.

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