LINUX.ORG.RU

Ответ на: комментарий от Kroz

Своя функция пишется минут за 5

Это я понимаю, но за пять наверно не получится. Там разные цвета строк и соответственно разные числа ([31m), и ещё эти символы встречаются в середине строки.

Просто подумалось, что может есть какая-нибудь готовая функция против этой заразы))).

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

Там разные цвета строк и соответственно разные числа ([31m), и ещё эти символы встречаются в середине строки.

Это зависит от задачи: ты пишешь для частного случая, или ты пишешь Ansifilter

Формат этой штуки вполне определен: <ESC>[{attr};{fg};{bg}m .

Написать самому будет быстрее, чем ждать ответа на форуме. https://stackoverflow.com/questions/14652538/remove-ascii-color-codes/1465276...

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

Это зависит от задачи: ты пишешь для частного случая

Частный. Я эти строки получаю от другой проги и посылаю их в Telegrambot, и вот зараза, там выводятся эти символы ))).

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

Интересно, можно ли отнести эту ситуацию к «недопиленности» Телеграма?

Нет.

Посмотрите пример удаления всех HTML-тегов из строки:

#include <stdio.h>
#include <string.h>

unsigned char is_html_tag(char *pos)
{
	return *pos == '<';
}

unsigned int get_tag_length(char *pos)
{
	char *closing_bracket_pos = strchr(pos, '>');
	if (closing_bracket_pos == NULL)
		return strlen(pos);
	return closing_bracket_pos - pos + 1;
}

void strip_html(char buf[])
{
	char *cur_source = buf, *cur_dest = buf;
	do {
		if (is_html_tag(cur_source))
			cur_source += get_tag_length(cur_source);
		
		if (cur_dest != cur_source)
			*cur_dest = *cur_source;
		
		if (*cur_source == '\0')
			break;
		
		++cur_source, ++cur_dest;
	} while (1);
}

void show_test(char buf[])
{
	printf("До обработки: \"%s\", ", buf);
	strip_html(buf);
	printf("После обработки: \"%s\"\n", buf);
}

int main(void)
{
	char test1[] = "alpha";
	char test2[] = "<beta>gamma</delta>";
	char test3[] = "epsilon<jotta";
	show_test(test1);
	show_test(test2);
	show_test(test3);

	return 0;
}

Northsoft ★★
()

Такое и правда минут за 5 пишется. Из этого минуты 3 уйдет на гуглеж как там эти последовательности для цвета задаются.

Сначала перематываешь указатель к первой попавшейся последовательности. Потом заводишь два указателя, которые будут пока указывать на одно и то же. Один исходный и будет увеличиваться каждый цикл, другой целевой и будет увеличиваться только когда последовательности нет. А потом в целевой пишешь то, что в исходном.

Я бы и кодом тебе написал, но еду в метро. :)

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

получаю от другой проги

Обычно «другие проги» при выводе в пайп/файл отключают ANSI-раскраску, либо имеют ключи комстроки на эту тему. Кроме того, они часто смотрят в переменные окружения на предмет ключей по умолчанию.

Не проще сперва посмотреть, нет ли у этой «другой проги» аналогичного поведения или ключей?

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 2)
Ответ на: комментарий от stD

Я эти строки получаю от другой проги и посылаю их в Telegrambo

Может у другой проги есть параметр --no-color?

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

Интересно, можно ли отнести эту ситуацию к «недопиленности» Телеграма?

Нет.

Почему?

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

Я бы и кодом тебе написал, но еду в метро. :)

Спасибо. Код я уже написал.

       while(indexin <= 254)
        { 
          if(buff[indexin] == '\x1b') 
           {
             for(; indexin <= 254; indexin++)
              { 
                if(buff[indexin] == 'm')
                 {  
                   buff[indexin] = ' ';
                   if(buff[indexin + 1] != '\x1b') indexin++;
                   break;
                 }          
              }
           }

          res_buff[indexout] = buff[indexin];

          if(res_buff[indexout] == '\n') 
           {
             res_buff[indexout] = 0;
             break;
           }

          indexin++;
          indexout++;

         }

        memset(buff, 0, 256);
        memset(res_buff, 0, 256);

Писал ночью, почти засыпая, поэтому он недоделанный.

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

Обычно «другие проги» при выводе в пайп/файл отключают ANSI-раскраску, либо имеют ключи

Нет, прога раскраску не отключает и ключей не имеет.

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

... а некоторые (почти все) еще и на тип терминала реагируют (env. var. TERM)...

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)
Ответ на: комментарий от stD

А Вы не могли бы показать свой вариант кода?

Так вам уже показали вырезатель html тегов. Всё получше ваших индексов и магических 254. А если всегда надо только в виде строк с установкой цвета в начале строки и сбросом цвета в конце строки, то и копировать никуда не надо. Двигаете указатель начала, а последний \x1b затираете на '\0'

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от stD

Как-то так наверное. Немного говнокодно, но мне лень проверять, в принципе должно работать. :)

void ClearString( char *psz )
{
	char *src, *dst;
	bool skip = 0;	
	
	if( !psz )
		return;
	
	src = dst = psz;
	
	// пропустить неизменяемую часть до первого спецсимвола
	for( ; *src && src != '\033'; src++; dst++ );
	
	for( ; *src; src++ )
	{
		// начало последовательности
		if( *src == '\033' )
		{
			skip = true;
			continue;
		}
		
		// конец последовательности
		if( *src == 'm' )
		{
			skip = false;
			continue;
		}
		
		// символы последовательности
		if( skip )
			continue;
		
		*dst = *src;
		dst++;
	}
	*dst = 0;
}
a1batross ★★★★★
()
Ответ на: комментарий от vodz

Так вам уже показали вырезатель html тегов. Всё получше ваших индексов и магических 254

Я начинающий и с указателями у меня проблемы, поэтому попросил готовый код. 254 - это у меня массив под строку выделен 256.

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

Остаётся только оттранслировать

Вот такая реакция:

dima@starik:~/Dropbox/ci/teleminer$ gcc -Wall -Wextra teleminerpipe.c -o teleminerpipe -lcrypto -lssl -pthread
teleminerpipe.c: In function ‘ClearString’:
teleminerpipe.c:245:2: error: unknown type name ‘bool’
  bool skip = 0; 
  ^
teleminerpipe.c:253:21: warning: comparison between pointer and integer [enabled by default]
  for( ; *src && src != '\033'; src++; dst++ );
                     ^
teleminerpipe.c:253:37: error: expected ‘)’ before ‘;’ token
  for( ; *src && src != '\033'; src++; dst++ );
                                     ^
teleminerpipe.c:260:11: error: ‘true’ undeclared (first use in this function)
    skip = true;
           ^
teleminerpipe.c:260:11: note: each undeclared identifier is reported only once for each function it appears in
teleminerpipe.c:267:11: error: ‘false’ undeclared (first use in this function)
    skip = false;
           ^
dima@starik:~/Dropbox/ci/teleminer$
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
stD
() автор топика
Ответ на: комментарий от Northsoft

Этот код сбойнёт на <p data-type=">unwanted">text</p>.

i-rinat ★★★★★
()
Ответ на: комментарий от a1batross

Ну я пытался написать, чтобы было понятно словами.

Этот ваш код удалит все 'm' из строки :) Не говоря уже, что не оттранслируется.

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

Вот оптимальнее и для любой ESC-последовательности.

static void
ClearString (char *src)
{
  char *dst;
  int skip = 1;

  if (!src)
        return;

  // пропустить неизменяемую часть до первого спецсимвола
  for (; *src != '\033'; src++)
        if(*src == '\0')
                return;

  for (dst = src; *src; src++) {
        // символы последовательности
        if (skip) {
          if ((*src >= 'A' && *src <= 'Z') || (*src >= 'a' && *src <= 'z'))
                skip = 0; // конец последовательности
          continue;
        }
        // начало последовательности
        if (*src == '\033') {
          skip = 1;
          continue;
        }

        *dst++ = *src;
  }
  *dst = 0;
}

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

ТС так и не осилил С. Переходи на веб макаку, это твое.

Пасть свою вонючую захлопни и мимо проходи.

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

Вот оптимальнее и для любой ESC-последовательности.

На вход Вашей функции подаю строки и в Телеграме вижу это:

2142 [0m
s: 1 [0m
uto. [0m
All. [0m
: 90 [0m
bled [0m
c... [0m
17c5 [0m
i:64 [0m
17c6 [0m

А должно быть так:

+-------------------------------------------------+
|         EWBF's Zcash CUDA miner. 0.3.4b         |
+-------------------------------------------------+
INFO: Current pool: zec.suprnova.cc:2142
INFO: Selected pools: 1
INFO: Solver: Auto.
INFO: Devices: All.
INFO: Temperature limit: 90
INFO: Api: Disabled
---------------------------------------------------
INFO: Target: 003c3c3c3c3c3c3c...
INFO: Detected new work: 43a
CUDA: Device: 0 GeForce GTX 460 SE, 961 MB i:64
stD
() автор топика
Ответ на: комментарий от stD

Причём вот это:

+-------------------------------------------------+
|         EWBF's Zcash CUDA miner. 0.3.4b         |
+-------------------------------------------------+

Вобще съело полностью.

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

Причём вот это: Вобще съело полностью.

Без цвета? Как оно может съесть, если когда нет цвета функция вообще не меняет входную строку? Вы что печатаете?

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

Не нужна никакая отдельная программа. Пропускайте через sed.

Во-первых, LOL. Охренеть ненужность, по какому такому критерию то? Во-вторых, у него это одна из функций, в прошло вопросе он решал проблему заставить писать этот минер построчно в пайп.

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

Без цвета? Как оно может съесть

Мне незачем Вас обманывать, вот скрин:

https://istarik.ru/uploads/images/00/00/01/2017/09/22/fe7183.png

Сверху отработал мой код, ниже Ваш.

Вот пример строки:

\x1b[36mTemp: \x1b[0m\x1b[36mGPU0: \x1b[0m\x1b[32m52C\x1b[0m

Вот так отправляю строку Вашей функции:

ClearString (buff); // buff - это char buff[256] = {0,}; 

И вот так отправляю сообщение Телеграму:

...
        // начало последовательности
        if (*src == '\x1b') {
          skip = 1;
          continue;
        }

        *dst++ = *src;
  }

  printf("DATA:%s\n", dst);
  SendMessage(glob_chat_id, dst);
  *dst = 0;
}

Может я что-то не правильно делаю?

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

решал проблему заставить писать этот минер построчно в пайп.

Так точно.

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

Может я что-то не правильно делаю?

Конечно. На то это и функция, что ей надо пользоваться, а не дописывать свой код как в main(). В функции, где делаете вызов там и печатать надо. Особо доставило это печать перед *dst=0...

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

Пропускайте через sed.

Подумал об этом в первую очередь. Однако в данном случае именно sed будет "Не нужна никакая отдельная программа".

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

Конечно. На то это и функция

Не понимаю Вас. Я из своей функции передал в Вашу функцию строку. Где я должен взять обработанную строку?

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

Не понимаю Вас. Я из своей функции передал в Вашу функцию строку. Где я должен взять обработанную строку?

Ну ваш код должен быть примерно таким:

popen "miner"
while читаем_строку_в_буфер_пока_не_EOF {
  ClearString(буфер)
  Печатем(буфер)
}

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

Ну ваш код должен быть примерно таким

Да всё работает. Спасибо. Я не знал, что можно так делать. И не понимаю как она возврашается (обработаея строка)?

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

Почему же такая простая и удобная функция не запилена, например, в <string.h>?

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

Я не знал, что можно так делать.

Охренеть. Вы же не вставляете в исходник функции, скажем popen(), свой код.

Ааа, понял, строка то никуда и не девается)))

:) Возвращать буфер принято там, где меняется указатель на начало, особенно если дополнительно выделена память. Но это в C. В C++ щас бы вам нарисовали std::string-и и уповали, что компилятор сам должен догадаться, что промежуточных строк не надо в этом алгоритме и развели срач, нужно ли тут GC.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Вы не вставляете в исходник функции, скажем popen(), свой код.

Не понял, здесь Вы про что говорите?

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

здесь Вы про что говорите?

Я там «же» вставил правкой. Смысл в том, что функции должны решать какую-то часть общей функциональности, следующая функция должна идти после предыдущей, а не внутри. Это настолько очевидно, что не сразу и поймёшь, что вы догадались вставить печать во внутрь функции. Разве не натолкнуло, что вот это *dst=0; — это неспроста? Иначе получалось, что это ненужный код.

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

Разве не натолкнуло, что вот это *dst=0;

Да, это забеспокоило сразу. Я уже писал, что боюсь указателей и не до конца понимаю как они клёво работают (по крайнер мере до сего момента :)) и поэтому думал, что раз я отправил строку в функцию, то оттуда её и нужно отправлять.

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

А Вы подумали что я Вашу функцию вставил в свою? )

Во-первых, вы разговариваете сами с собой :) Во-вторых, я не подумал, а с небольшим усилием догадался, а потом вы и подтвердили. То что она осталась отдельной функцией не важно, важно, что вы вставили что-то туда, где выше был и return при отсутствии установки цвета в строке и вывод при сдвинутом указателе и не закрытой последней ESC-последовательности в строке.

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