LINUX.ORG.RU

esc-последовательности и терминал

 , ,


1

2

Как передать параметры типа int в строку, которую нужно записать в файл терминала tty1? Пробовал через define, но не получается, константы воспринимаются как символы строки.

int function(int x, int y)
{
    #define _X_ x
    #define _Y_ y

    int file = open("/dev/tty1", O_WRONLY);
    char str[] = "\033[_X_;_Y_H";
    write(file, str, sizeof(str));
    close(file);

    return 0;
}

#include <fcntl.h>

#define function(x, y) do { \
    int file = open("/dev/tty", O_WRONLY); \
    char str[] = "\033[" #x ";" #y "H"; \
    write(file, str, sizeof(str)); \
    close(file); \
 } while(0)

int main(void)
{
        function(2, 3);
        return 0;
}
vodz ★★★★★
()

Видимо, ты пришёл в C из Perl. Такой способ подстановки в строку в C не работает.

char str[20] = {0};
sprintf(str, "\033[%d;%dH", x, y);
write(file, str, strlen(str));
Почитай на досуге про printf.

E ★★★
()
Ответ на: комментарий от E

char str[20] = {0};

А вот это откуда Вы пришли? :) Из отдела ИБ? Давайте будем тормозить на ровном месте, но зато будет выглядеть безопасно хоть и абсурдно?

vodz ★★★★★
()
Ответ на: комментарий от kennydzzze

А есть решение этой же проблемы без определения функции макросом?

Можно объявить макрос #define _X_(x) #x, но это тоже будет работать только для констант, для переменных вам общий принцип был показан E, хоть и крайне неоптимальным образом.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Не оптимальность выражается в выделении лишних байт под строку при инициализации? Если да, то как можно лучше оформить код? Работа со списком думаю могла бы подойти, но я верю, что есть решения куда проще.

kennydzzze
() автор топика
Ответ на: комментарий от kennydzzze

Не только. Зачем-то делается strlen, хотя перед этим вызывается sprintf. Да и вообще, dprintf бы заменил всё - и буфер и write. Откуда там у вас список?

vodz ★★★★★
()
Ответ на: комментарий от vodz

Насчет dprintf спорно, ибо если на то пошло, можно было бы и обычным printfом обойтись для таких простых целей, но мне в учебном заведении сказали использовать write, от сюда все велосипеды и едут.

kennydzzze
() автор топика
Ответ на: комментарий от kennydzzze

Ну раз в учебном... Вообще-то dprintf это уже давно стандарт: POSIX.1-2008, а для обычного printf надо ещё fopen/fclose. Но у вас действительно в задаче поставлено условие с макросами? Что-то сильно сомнительно.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Я и не говорил, что мне нужно работать с макросами. Я говорил, что я пробовал работать с ними. Я не хотел изначально городить телеги(sprintf в данном случае), чтобы корректно записать в строку esc-послед. Насчет fopen, я имел ввиду, что если выбирать самое простое для такой задачи, то можно было бы обойтись вообще без файлов терминала и fopenов. Просто вывести в терминал через обычный printf нужную последовательность, что-то вроде echo, если в bashе писать. Но если подходить грамотно к решению этой задачи, то dprintf подошел бы лучше всех, не спорю.

kennydzzze
() автор топика
Ответ на: комментарий от kennydzzze

Хм, а файл терминала - это тоже вы получается сами придумали? Похоже вам придётся начать с начала - привести изначальные условия задачи.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Вы меня не понимаете. Я сначала просто баловался с этими esc-последовательностями в bashe, используя команду echo, разбирался как это работает все. Затем передо мной встала конкретная задача: написать библиотеку, которая имела бы ряд функций (указать место каретки, изменить цвета фона/символов и т.д.). Я эти функции изначально писал используя printf, все работало, но мне сказали, что нужно работать с файлом терминала. Соответственно нужно было добавить функции open, close, write и изменить каждую функцию, что сейчас собственно я уже и сделал.

kennydzzze
() автор топика
Ответ на: комментарий от kennydzzze

Вам похоже не совсем корректно сказали. Имелось наверное перехват вывода на терминал и самостоятельная буферизация. Хорошая библиотека не такая уж простая задача, почитайте о curses и как работает screen.

vodz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.