Ошибка цветного вывода в консоль

Рейтинг: 2Ответов: 2Опубликовано: 13.07.2023

Я пытаюсь сделать цветной вывод в консоли и столкнулся с проблемой. При выводе цветных символов появились аномалии (они появляются в любом варианте вывода, причем такой же код на python работает нормально).

#include <iostream>
#include "windows.h"
#include <sstream>

using namespace std;

stringstream ss;
string pixel(float r, float g, float b, string str = " "){
    ss.clear();
    ss << "\033[48;2;" << r << ";" << g <<";" << b <<"m"<< str <<"\033[0;0m";
    return ss.str();
}


int main(){
    cout << pixel(0, 0, 0) + pixel(0, 255, 0)<<endl;
}

Вывод этого кода (пробел с измененным задним фоном)(зеленый??, пробел??, зеленый): введите сюда описание изображения

А вот так должно быть: введите сюда описание изображения

Черный "пиксель", потом зеленый, без пробела.

Код на python:

def rgbPrint(rgb):
    print(f"\033[48;2;{rgb[0]};{rgb[1]};{rgb[2]}m \033[0;0m", end = '')

rgbPrint([0, 0, 0])
rgbPrint([0, 255, 0])

OS: Windows 11

компилятор: g++ version 7.3.0

Консоль: стандартная, "cmd.exe" в терминале Windows 11

Инфу о том, как сделать RGB в консоли брал отсюда

Ответы

▲ 4Принят

Я бы хотел отметить три момента:

Использование глобальной переменной stringstream ss; - видимо чтобы переиспользовать эту переменную в начале делается вызов ss.clear();, однако это не ::std::sting и этот метод не подчищает ранее записанное содержимое, вместо этого он сбрасывает флаги состояния потока, так как это метод, унаследованный от std::basic_ios. Для удаления ранее записанного содержимого придется делать ss.str(::std::string{}), а лучше - просто сделать ss локальной переменной.

При вызове pixel(0, 0, 0) + pixel(0, 255, 0) записывается три символа, причем символ, оставшийся в ss при первом вызове, будет записан дважды. При этом в С++ еще и не определен порядок вызова этих функций, так что код может выдавать как зеленый - черный - зеленый, так и черный - черный - зеленый.

Консоль cmd.exe, хотя и обрабатывает расширенные цветовые директивы, однако вместо указанного цвета будет отображать ближайший из палитры 256 цветов. Если это нужно, то имеет смысл попробовать windows terminal.

▲ 1

Вместо ss.clear() используй ss = {} или ss.str("")

Метод clear() сбрасывает ошибку, вроде. Но это не точно.

Вот так работает, как надо:

#include <iostream>
#include "windows.h"
#include <sstream>

using namespace std;

stringstream ss;

string pixel(float r, float g, float b, string str = " ") {
    
    ss.str("");

    ss << "\033[48;2;" << r << ";" << g << ";" << b << "m" << str << "\033[0;0m";

    return ss.str();
}


int main() {
    cout << pixel(0, 0, 0) + pixel(0, 255, 0) << endl;
}